import { BLOCKHASH_BYTELENGTH, KEY_BYTELENGTH } from './constants'
import { Blake2b } from './ed25519/blake2b'
-import { ge_double_scalarmult_vartime_to_p3, ge_frombytes, ge_frombytes_negate_vartime, ge_has_small_order, ge_is_canonical } from './ed25519/ge'
+import { ge_double_scalarmult_vartime, ge_frombytes, ge_frombytes_negate_vartime, ge_has_small_order, ge_is_canonical } from './ed25519/ge'
import { ge_p3, ge_p3_tobytes, ge_sub_p3 } from './ed25519/p'
import { sc_is_canonical, sc_reduce } from './ed25519/sc'
import { equalbytes } from './ed25519/utils'
blake2b.init().update(sig, 32).update(pub, KEY_BYTELENGTH).update(M, BLOCKHASH_BYTELENGTH).digest(h)
sc_reduce(h)
- ge_double_scalarmult_vartime_to_p3(sb_ah, h, A, S)
+ ge_double_scalarmult_vartime(sb_ah, h, A, S)
ge_p3_tobytes(check_r, sb_ah)
return equalbytes(sig, check_r, KEY_BYTELENGTH)
blake2b.init().update(sig, 32).update(pub, 32).update(M, mlen).digest(h)
sc_reduce(h)
- ge_double_scalarmult_vartime_to_p3(sb_ah, h, A, S)
+ ge_double_scalarmult_vartime(sb_ah, h, A, S)
ge_sub_p3(check, expected_r, sb_ah)
return ge_has_small_order(check)
blake2b.init().update(sig, 32).update(pub, 32).update(M, mlen).digest(h)
sc_reduce(h)
- ge_double_scalarmult_vartime_to_p3(sb_ah, h, A, S)
+ ge_double_scalarmult_vartime(sb_ah, h, A, S)
ge_sub_p3(check, expected_r, sb_ah)
ge_p3_tobytes(check_r, sb_ah)
* @param hx FieldElement power destination
* @param fx FieldElement base source
*/
-export function fe_sq_vec (hx: FieldElement, fx: FieldElement, hy: FieldElement, fy: FieldElement): void {
+export function fe_sq_vec (hx: FieldElement, hy: FieldElement, fx: FieldElement, fy: FieldElement): void {
const fx_ptr: usize = changetype<usize>(fx)
const fy_ptr: usize = changetype<usize>(fy)
const f0: v128 = i32x4(load<i32>(fx_ptr, 0), load<i32>(fy_ptr, 0), 0, 0)
*
* Here the group is the set of pairs (x,y) of field elements satisfying
*
- * -x² + y² = 1 + d x²y²
+ * -x² + y² = 1 + dx²y²
*
* where d = -121665/121666.
*
new ge_cached(),
new ge_cached()
]) /* A,3A,5A,7A,9A,11A,13A,15A */
+const ge_double_scalarmult_vartime_p: ge_p2 = new ge_p2()
const ge_double_scalarmult_vartime_t: ge_p1p1 = new ge_p1p1()
const ge_double_scalarmult_vartime_u: ge_p3 = new ge_p3()
const ge_double_scalarmult_vartime_A2: ge_p3 = new ge_p3()
*
* Only used for signatures verification.
*/
-function ge_double_scalarmult_vartime (r: ge_p2, a: StaticArray<u8>, A: ge_p3, b: StaticArray<u8>): void {
+export function ge_double_scalarmult_vartime (r: ge_p3, a: StaticArray<u8>, A: ge_p3, b: StaticArray<u8>): void {
const Bi = base2
const aslide = ge_double_scalarmult_vartime_aslide
const bslide = ge_double_scalarmult_vartime_bslide
const Ai = ge_double_scalarmult_vartime_Ai /* A,3A,5A,7A,9A,11A,13A,15A */
+ const p = ge_double_scalarmult_vartime_p
const t = ge_double_scalarmult_vartime_t
const u = ge_double_scalarmult_vartime_u
const A2 = ge_double_scalarmult_vartime_A2
ge_p1p1_to_p3(u, t)
ge_p3_to_cached(Ai[7], u)
- ge_p2_0(r)
+ ge_p2_0(p)
for (i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) {
}
for (; i >= 0; --i) {
- ge_p2_dbl(t, r)
+ ge_p2_dbl(t, p)
if (aslide[i] > 0) {
ge_p1p1_to_p3(u, t)
ge_sub_precomp(t, u, Bi[(-bslide[i]) / 2])
}
- ge_p1p1_to_p2(r, t)
+ ge_p1p1_to_p2(p, t)
}
-}
-const ge_double_scalarmult_vartime_p: ge_p2 = new ge_p2()
-export function ge_double_scalarmult_vartime_to_p3 (r: ge_p3, a: StaticArray<u8>, A: ge_p3, b: StaticArray<u8>): void {
- const p = ge_double_scalarmult_vartime_p
- ge_double_scalarmult_vartime(p, a, A, b)
ge_p2_to_p3(r, p)
}
fe_1(h.Z)
}
-const ge_p2_dbl_t0: FieldElement = fe()
+const ge_p2_dbl_t: FieldElement = fe()
+/**
+ * r = 2 * p
+ */
//@ts-expect-error
@inline
export function ge_p2_dbl (r: ge_p1p1, p: ge_p2): void {
- const t0 = ge_p2_dbl_t0
- fe_sq_vec(r.X, p.X, r.Z, p.Y)
+ const t = ge_p2_dbl_t
+ fe_sq_vec(r.X, r.Z, p.X, p.Y)
fe_sq2(r.T, p.Z)
fe_add(r.Y, p.X, p.Y)
- fe_sq(t0, r.Y)
+ fe_sq(t, r.Y)
fe_add(r.Y, r.Z, r.X)
fe_sub(r.Z, r.Z, r.X)
- fe_sub(r.X, t0, r.Y)
+ fe_sub(r.X, t, r.Y)
fe_sub(r.T, r.T, r.Z)
}
//@ts-expect-error
@inline
export function ge_p1p1_0 (h: ge_p1p1): void {
- ge_p2_0(h)
+ fe_0(h.X)
+ fe_1(h.Y)
+ fe_1(h.Z)
fe_0(h.T)
}
//@ts-expect-error
@inline
export function ge_p3_0 (h: ge_p3): void {
- ge_p2_0(h)
+ fe_0(h.X)
+ fe_1(h.Y)
+ fe_1(h.Z)
fe_0(h.T)
}
-const ge_p3_dbl_q: ge_p2 = new ge_p2()
+const ge_p3_dbl_t: FieldElement = fe()
/**
* r = 2 * p
+ *
+ * p.T is used as the temporary holder for r.Y² because the parameter is unused
+ * hereafter at all call sites and it eliminates an extra `t` buffer.
*/
export function ge_p3_dbl (r: ge_p1p1, p: ge_p3): void {
- const q = ge_p3_dbl_q
- fe_copy(q.X, p.X)
- fe_copy(q.Y, p.Y)
- fe_copy(q.Z, p.Z)
- ge_p2_dbl(r, q)
+ const t = ge_p3_dbl_t
+ fe_sq_vec(r.X, r.Z, p.X, p.Y)
+ fe_sq2(r.T, p.Z)
+ fe_add(r.Y, p.X, p.Y)
+ fe_sq(t, r.Y)
+ fe_add(r.Y, r.Z, r.X)
+ fe_sub(r.Z, r.Z, r.X)
+ fe_sub(r.X, t, r.Y)
+ fe_sub(r.T, r.T, r.Z)
}
const ge_p3_tobytes_recip: FieldElement = fe()