core/crypto/_weierstrass: Add scalar field inversion

This commit is contained in:
Yawning Angel
2026-02-13 07:36:15 +09:00
parent aea6274a10
commit ffa6fc2a67
4 changed files with 677 additions and 5 deletions

View File

@@ -135,7 +135,7 @@ fe_equal :: proc "contextless" (arg1, arg2: ^Montgomery_Domain_Field_Element) ->
tmp: Montgomery_Domain_Field_Element = ---
fe_sub(&tmp, arg1, arg2)
is_eq := subtle.u64_is_zero(fe_non_zero(&tmp))
is_eq := subtle.eq(fe_non_zero(&tmp), 0)
fe_clear(&tmp)
@@ -208,3 +208,271 @@ fe_cond_negate :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Eleme
fe_clear(&tmp1)
}
fe_pow2k :: proc "contextless" (
out1: ^Montgomery_Domain_Field_Element,
arg1: ^Montgomery_Domain_Field_Element,
arg2: uint,
) {
// Special case: `arg1^(2 * 0) = 1`, though this should never happen.
if arg2 == 0 {
fe_one(out1)
return
}
fe_square(out1, arg1)
for _ in 1 ..< arg2 {
fe_square(out1, out1)
}
}
fe_inv :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
// Inversion computation is derived from the addition chain:
//
// _10 = 2*1
// _100 = 2*_10
// _101 = 1 + _100
// _110 = 1 + _101
// _1001 = _100 + _101
// _1111 = _110 + _1001
// _10010 = 2*_1001
// _10101 = _110 + _1111
// _11000 = _110 + _10010
// _11010 = _10 + _11000
// _101111 = _10101 + _11010
// _111000 = _1001 + _101111
// _111101 = _101 + _111000
// _111111 = _10 + _111101
// _1001111 = _10010 + _111101
// _1100001 = _10010 + _1001111
// _1100011 = _10 + _1100001
// _1110011 = _10010 + _1100001
// _1110111 = _100 + _1110011
// _1111101 = _110 + _1110111
// _10010101 = _11000 + _1111101
// _10100111 = _10010 + _10010101
// _10101101 = _110 + _10100111
// _11100101 = _111000 + _10101101
// _11111111 = _11010 + _11100101
// x16 = _11111111 << 8 + _11111111
// x32 = x16 << 16 + x16
// i133 = ((x32 << 48 + x16) << 16 + x16) << 16
// i158 = ((x16 + i133) << 16 + x16) << 6 + _101111
// i186 = ((i158 << 9 + _1110011) << 8 + _1111101) << 9
// i206 = ((_10101101 + i186) << 8 + _10100111) << 9 + _101111
// i236 = ((i206 << 8 + _111101) << 11 + _1001111) << 9
// i257 = ((_1110111 + i236) << 10 + _11100101) << 8 + _1100001
// i286 = ((i257 << 7 + _111111) << 10 + _1100011) << 10
// return (_10010101 + i286) << 6 + _1111
//
// Operations: 251 squares 43 multiplies
//
// Generated by github.com/mmcloughlin/addchain v0.4.0.
// Note: Need to stash `arg1` (`xx`) in the case that `out1`/`arg1` alias,
// as `arg1` is used after `out1` has been altered.
t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, xx: Montgomery_Domain_Field_Element = ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, arg1^
// Step 1: t1 = x^0x2
fe_square(&t1, arg1)
// Step 2: t5 = x^0x4
fe_square(&t5, &t1)
// Step 3: t2 = x^0x5
fe_mul(&t2, arg1, &t5)
// Step 4: t10 = x^0x6
fe_mul(&t10, arg1, &t2)
// Step 5: t3 = x^0x9
fe_mul(&t3, &t5, &t2)
// Step 6: z = x^0xf
fe_mul(out1, &t10, &t3)
// Step 7: t9 = x^0x12
fe_square(&t9, &t3)
// Step 8: t4 = x^0x15
fe_mul(&t4, &t10, out1)
// Step 9: t0 = x^0x18
fe_mul(&t0, &t10, &t9)
// Step 10: t13 = x^0x1a
fe_mul(&t13, &t1, &t0)
// Step 11: t8 = x^0x2f
fe_mul(&t8, &t4, &t13)
// Step 12: t4 = x^0x38
fe_mul(&t4, &t3, &t8)
// Step 13: t7 = x^0x3d
fe_mul(&t7, &t2, &t4)
// Step 14: t2 = x^0x3f
fe_mul(&t2, &t1, &t7)
// Step 15: t6 = x^0x4f
fe_mul(&t6, &t9, &t7)
// Step 16: t3 = x^0x61
fe_mul(&t3, &t9, &t6)
// Step 17: t1 = x^0x63
fe_mul(&t1, &t1, &t3)
// Step 18: t12 = x^0x73
fe_mul(&t12, &t9, &t3)
// Step 19: t5 = x^0x77
fe_mul(&t5, &t5, &t12)
// Step 20: t11 = x^0x7d
fe_mul(&t11, &t10, &t5)
// Step 21: t0 = x^0x95
fe_mul(&t0, &t0, &t11)
// Step 22: t9 = x^0xa7
fe_mul(&t9, &t9, &t0)
// Step 23: t10 = x^0xad
fe_mul(&t10, &t10, &t9)
// Step 24: t4 = x^0xe5
fe_mul(&t4, &t4, &t10)
// Step 25: t13 = x^0xff
fe_mul(&t13, &t13, &t4)
// Step 33: t14 = x^0xff00
fe_pow2k(&t14, &t13, 8)
// Step 34: t13 = x^0xffff
fe_mul(&t13, &t13, &t14)
// Step 50: t14 = x^0xffff0000
fe_pow2k(&t14, &t13, 16)
// Step 51: t14 = x^0xffffffff
fe_mul(&t14, &t13, &t14)
// Step 99: t14 = x^0xffffffff000000000000
fe_pow2k(&t14, &t14, 48)
// Step 100: t14 = x^0xffffffff00000000ffff
fe_mul(&t14, &t13, &t14)
// Step 116: t14 = x^0xffffffff00000000ffff0000
fe_pow2k(&t14, &t14, 16)
// Step 117: t14 = x^0xffffffff00000000ffffffff
fe_mul(&t14, &t13, &t14)
// Step 133: t14 = x^0xffffffff00000000ffffffff0000
fe_pow2k(&t14, &t14, 16)
// Step 134: t14 = x^0xffffffff00000000ffffffffffff
fe_mul(&t14, &t13, &t14)
// Step 150: t14 = x^0xffffffff00000000ffffffffffff0000
fe_pow2k(&t14, &t14, 16)
// Step 151: t13 = x^0xffffffff00000000ffffffffffffffff
fe_mul(&t13, &t13, &t14)
// Step 157: t13 = x^0x3fffffffc00000003fffffffffffffffc0
fe_pow2k(&t13, &t13, 6)
// Step 158: t13 = x^0x3fffffffc00000003fffffffffffffffef
fe_mul(&t13, &t8, &t13)
// Step 167: t13 = x^0x7fffffff800000007fffffffffffffffde00
fe_pow2k(&t13, &t13, 9)
// Step 168: t12 = x^0x7fffffff800000007fffffffffffffffde73
fe_mul(&t12, &t12, &t13)
// Step 176: t12 = x^0x7fffffff800000007fffffffffffffffde7300
fe_pow2k(&t12, &t12, 8)
// Step 177: t11 = x^0x7fffffff800000007fffffffffffffffde737d
fe_mul(&t11, &t11, &t12)
// Step 186: t11 = x^0xffffffff00000000ffffffffffffffffbce6fa00
fe_pow2k(&t11, &t11, 9)
// Step 187: t10 = x^0xffffffff00000000ffffffffffffffffbce6faad
fe_mul(&t10, &t10, &t11)
// Step 195: t10 = x^0xffffffff00000000ffffffffffffffffbce6faad00
fe_pow2k(&t10, &t10, 8)
// Step 196: t9 = x^0xffffffff00000000ffffffffffffffffbce6faada7
fe_mul(&t9, &t9, &t10)
// Step 205: t9 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e00
fe_pow2k(&t9, &t9, 9)
// Step 206: t8 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e2f
fe_mul(&t8, &t8, &t9)
// Step 214: t8 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e2f00
fe_pow2k(&t8, &t8, 8)
// Step 215: t7 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e2f3d
fe_mul(&t7, &t7, &t8)
// Step 226: t7 = x^0xffffffff00000000ffffffffffffffffbce6faada7179e800
fe_pow2k(&t7, &t7, 11)
// Step 227: t6 = x^0xffffffff00000000ffffffffffffffffbce6faada7179e84f
fe_mul(&t6, &t6, &t7)
// Step 236: t6 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e2f3d09e00
fe_pow2k(&t6, &t6, 9)
// Step 237: t5 = x^0x1fffffffe00000001ffffffffffffffff79cdf55b4e2f3d09e77
fe_mul(&t5, &t5, &t6)
// Step 247: t5 = x^0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dc00
fe_pow2k(&t5, &t5, 10)
// Step 248: t4 = x^0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5
fe_mul(&t4, &t4, &t5)
// Step 256: t4 = x^0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce500
fe_pow2k(&t4, &t4, 8)
// Step 257: t3 = x^0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce561
fe_mul(&t3, &t3, &t4)
// Step 264: t3 = x^0x3fffffffc00000003fffffffffffffffef39beab69c5e7a13cee72b080
fe_pow2k(&t3, &t3, 7)
// Step 265: t2 = x^0x3fffffffc00000003fffffffffffffffef39beab69c5e7a13cee72b0bf
fe_mul(&t2, &t2, &t3)
// Step 275: t2 = x^0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc00
fe_pow2k(&t2, &t2, 10)
// Step 276: t1 = x^0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63
fe_mul(&t1, &t1, &t2)
// Step 286: t1 = x^0x3fffffffc00000003fffffffffffffffef39beab69c5e7a13cee72b0bf18c00
fe_pow2k(&t1, &t1, 10)
// Step 287: t0 = x^0x3fffffffc00000003fffffffffffffffef39beab69c5e7a13cee72b0bf18c95
fe_mul(&t0, &t0, &t1)
// Step 293: t0 = x^0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540
fe_pow2k(&t0, &t0, 6)
// Step 294: z = x^0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f
fe_mul(out1, out1, &t0)
fe_clear_vec([]^Montgomery_Domain_Field_Element{&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &t10, &t11, &t12, &t13, &t14, &xx})
}

View File

@@ -148,7 +148,7 @@ fe_equal :: proc "contextless" (arg1, arg2: ^Montgomery_Domain_Field_Element) ->
tmp: Montgomery_Domain_Field_Element = ---
fe_sub(&tmp, arg1, arg2)
is_eq := subtle.u64_is_zero(fe_non_zero(&tmp))
is_eq := subtle.eq(fe_non_zero(&tmp), 0)
fe_clear(&tmp)
@@ -237,3 +237,371 @@ fe_cond_negate :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Eleme
fe_clear(&tmp1)
}
fe_pow2k :: proc "contextless" (
out1: ^Montgomery_Domain_Field_Element,
arg1: ^Montgomery_Domain_Field_Element,
arg2: uint,
) {
// Special case: `arg1^(2 * 0) = 1`, though this should never happen.
if arg2 == 0 {
fe_one(out1)
return
}
fe_square(out1, arg1)
for _ in 1 ..< arg2 {
fe_square(out1, out1)
}
}
fe_inv :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
// Inversion computation is derived from the addition chain:
//
// _10 = 2*1
// _11 = 1 + _10
// _101 = _10 + _11
// _111 = _10 + _101
// _1001 = _10 + _111
// _1011 = _10 + _1001
// _1101 = _10 + _1011
// _1111 = _10 + _1101
// _11110 = 2*_1111
// _11111 = 1 + _11110
// _1111100 = _11111 << 2
// i14 = _1111100 << 2
// i26 = (i14 << 3 + _1111100) << 7 + i14
// i42 = i26 << 15 + i26
// x64 = i42 << 30 + i42 + _1111
// x128 = x64 << 64 + x64
// x192 = x128 << 64 + x64
// x194 = x192 << 2 + _11
// i225 = ((x194 << 6 + _111) << 3 + _11) << 7
// i235 = 2*((_1101 + i225) << 6 + _1101) + 1
// i258 = ((i235 << 11 + _11111) << 2 + 1) << 8
// i269 = ((_1101 + i258) << 2 + _11) << 6 + _1011
// i286 = ((i269 << 4 + _111) << 6 + _11111) << 5
// i308 = ((_1011 + i286) << 10 + _1101) << 9 + _1101
// i323 = ((i308 << 4 + _1011) << 6 + _1001) << 3
// i340 = ((1 + i323) << 7 + _1011) << 7 + _101
// i357 = ((i340 << 5 + _111) << 5 + _1111) << 5
// i369 = ((_1011 + i357) << 4 + _1011) << 5 + _111
// i387 = ((i369 << 3 + _11) << 7 + _11) << 6
// i397 = ((_1011 + i387) << 4 + _101) << 3 + _11
// i413 = ((i397 << 4 + _11) << 4 + _11) << 6
// i427 = ((_101 + i413) << 5 + _101) << 6 + _1011
// return (2*i427 + 1) << 4 + 1
//
// Operations: 381 squares 53 multiplies
//
// Generated by github.com/mmcloughlin/addchain v0.4.0.
// Note: Need to stash `arg1` (`xx`) in the case that `out1`/`arg1` alias,
// as `arg1` is used after `out1` has been altered.
t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, xx: Montgomery_Domain_Field_Element = ---, ---, ---, ---, ---, ---, ---, ---, ---, ---, arg1^
// Step 1: t3 = x^0x2
fe_square(&t3, arg1)
// Step 2: t1 = x^0x3
fe_mul(&t1, arg1, &t3)
// Step 3: t0 = x^0x5
fe_mul(&t0, &t3, &t1)
// Step 4: t2 = x^0x7
fe_mul(&t2, &t3, &t0)
// Step 5: t4 = x^0x9
fe_mul(&t4, &t3, &t2)
// Step 6: z = x^0xb
fe_mul(out1, &t3, &t4)
// Step 7: t5 = x^0xd
fe_mul(&t5, &t3, out1)
// Step 8: t3 = x^0xf
fe_mul(&t3, &t3, &t5)
// Step 9: t6 = x^0x1e
fe_square(&t6, &t3)
// Step 10: t6 = x^0x1f
fe_mul(&t6, &xx, &t6)
// Step 12: t8 = x^0x7c
fe_pow2k(&t8, &t6, 2)
// Step 14: t7 = x^0x1f0
fe_pow2k(&t7, &t8, 2)
// Step 17: t9 = x^0xf80
fe_pow2k(&t9, &t7, 3)
// Step 18: t8 = x^0xffc
fe_mul(&t8, &t8, &t9)
// Step 25: t8 = x^0x7fe00
fe_pow2k(&t8, &t8, 7)
// Step 26: t7 = x^0x7fff0
fe_mul(&t7, &t7, &t8)
// Step 41: t8 = x^0x3fff80000
fe_pow2k(&t8, &t7, 15)
// Step 42: t7 = x^0x3fffffff0
fe_mul(&t7, &t7, &t8)
// Step 72: t8 = x^0xfffffffc00000000
fe_pow2k(&t8, &t7, 30)
// Step 73: t7 = x^0xfffffffffffffff0
fe_mul(&t7, &t7, &t8)
// Step 74: t7 = x^0xffffffffffffffff
fe_mul(&t7, &t3, &t7)
// Step 138: t8 = x^0xffffffffffffffff0000000000000000
fe_pow2k(&t8, &t7, 64)
// Step 139: t8 = x^0xffffffffffffffffffffffffffffffff
fe_mul(&t8, &t7, &t8)
// Step 203: t8 = x^0xffffffffffffffffffffffffffffffff0000000000000000
fe_pow2k(&t8, &t8, 64)
// Step 204: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffff
fe_mul(&t7, &t7, &t8)
// Step 206: t7 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffc
fe_pow2k(&t7, &t7, 2)
// Step 207: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff
fe_mul(&t7, &t1, &t7)
// Step 213: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc0
fe_pow2k(&t7, &t7, 6)
// Step 214: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7
fe_mul(&t7, &t2, &t7)
// Step 217: t7 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe38
fe_pow2k(&t7, &t7, 3)
// Step 218: t7 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b
fe_mul(&t7, &t1, &t7)
// Step 225: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d80
fe_pow2k(&t7, &t7, 7)
// Step 226: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d
fe_mul(&t7, &t5, &t7)
// Step 232: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc76340
fe_pow2k(&t7, &t7, 6)
// Step 233: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d
fe_mul(&t7, &t5, &t7)
// Step 234: t7 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69a
fe_square(&t7, &t7)
// Step 235: t7 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b
fe_mul(&t7, &xx, &t7)
// Step 246: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d800
fe_pow2k(&t7, &t7, 11)
// Step 247: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f
fe_mul(&t7, &t6, &t7)
// Step 249: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607c
fe_pow2k(&t7, &t7, 2)
// Step 250: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d
fe_mul(&t7, &xx, &t7)
// Step 258: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d00
fe_pow2k(&t7, &t7, 8)
// Step 259: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0d
fe_mul(&t7, &t5, &t7)
// Step 261: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f434
fe_pow2k(&t7, &t7, 2)
// Step 262: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f437
fe_mul(&t7, &t1, &t7)
// Step 268: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dc0
fe_pow2k(&t7, &t7, 6)
// Step 269: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb
fe_mul(&t7, out1, &t7)
// Step 273: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb0
fe_pow2k(&t7, &t7, 4)
// Step 274: t7 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb7
fe_mul(&t7, &t2, &t7)
// Step 280: t7 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372dc0
fe_pow2k(&t7, &t7, 6)
// Step 281: t6 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf
fe_mul(&t6, &t6, &t7)
// Step 286: t6 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbe0
fe_pow2k(&t6, &t6, 5)
// Step 287: t6 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb
fe_mul(&t6, out1, &t6)
// Step 297: t6 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac00
fe_pow2k(&t6, &t6, 10)
// Step 298: t6 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d
fe_mul(&t6, &t5, &t6)
// Step 307: t6 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a00
fe_pow2k(&t6, &t6, 9)
// Step 308: t5 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0d
fe_mul(&t5, &t5, &t6)
// Step 312: t5 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0d0
fe_pow2k(&t5, &t5, 4)
// Step 313: t5 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db
fe_mul(&t5, out1, &t5)
// Step 319: t5 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c0
fe_pow2k(&t5, &t5, 6)
// Step 320: t4 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c9
fe_mul(&t4, &t4, &t5)
// Step 323: t4 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b648
fe_pow2k(&t4, &t4, 3)
// Step 324: t4 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b649
fe_mul(&t4, &xx, &t4)
// Step 331: t4 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db2480
fe_pow2k(&t4, &t4, 7)
// Step 332: t4 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b
fe_mul(&t4, out1, &t4)
// Step 339: t4 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d924580
fe_pow2k(&t4, &t4, 7)
// Step 340: t4 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d924585
fe_mul(&t4, &t0, &t4)
// Step 345: t4 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a0
fe_pow2k(&t4, &t4, 5)
// Step 346: t4 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a7
fe_mul(&t4, &t2, &t4)
// Step 351: t4 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614e0
fe_pow2k(&t4, &t4, 5)
// Step 352: t3 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614ef
fe_mul(&t3, &t3, &t4)
// Step 357: t3 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29de0
fe_pow2k(&t3, &t3, 5)
// Step 358: t3 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29deb
fe_mul(&t3, out1, &t3)
// Step 362: t3 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29deb0
fe_pow2k(&t3, &t3, 4)
// Step 363: t3 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb
fe_mul(&t3, out1, &t3)
// Step 368: t3 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd760
fe_pow2k(&t3, &t3, 5)
// Step 369: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd767
fe_mul(&t2, &t2, &t3)
// Step 372: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb38
fe_pow2k(&t2, &t2, 3)
// Step 373: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b
fe_mul(&t2, &t1, &t2)
// Step 380: t2 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614ef5d9d80
fe_pow2k(&t2, &t2, 7)
// Step 381: t2 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614ef5d9d83
fe_mul(&t2, &t1, &t2)
// Step 387: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760c0
fe_pow2k(&t2, &t2, 6)
// Step 388: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb
fe_mul(&t2, out1, &t2)
// Step 392: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb0
fe_pow2k(&t2, &t2, 4)
// Step 393: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb5
fe_mul(&t2, &t0, &t2)
// Step 396: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065a8
fe_pow2k(&t2, &t2, 3)
// Step 397: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065ab
fe_mul(&t2, &t1, &t2)
// Step 401: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065ab0
fe_pow2k(&t2, &t2, 4)
// Step 402: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065ab3
fe_mul(&t2, &t1, &t2)
// Step 406: t2 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065ab30
fe_pow2k(&t2, &t2, 4)
// Step 407: t1 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffff1d8d3607d0dcb77d606836c922c29debb3b065ab33
fe_mul(&t1, &t1, &t2)
// Step 413: t1 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc0
fe_pow2k(&t1, &t1, 6)
// Step 414: t1 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5
fe_mul(&t1, &t0, &t1)
// Step 419: t1 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614ef5d9d832d5998a0
fe_pow2k(&t1, &t1, 5)
// Step 420: t0 = x^0x1ffffffffffffffffffffffffffffffffffffffffffffffff8ec69b03e86e5bbeb0341b6491614ef5d9d832d5998a5
fe_mul(&t0, &t0, &t1)
// Step 426: t0 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb56662940
fe_pow2k(&t0, &t0, 6)
// Step 427: z = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb5666294b
fe_mul(out1, out1, &t0)
// Step 428: z = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296
fe_square(out1, out1)
// Step 429: z = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5297
fe_mul(out1, &xx, out1)
// Step 433: z = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970
fe_pow2k(out1, out1, 4)
// Step 434: z = x^0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52971
fe_mul(out1, &xx, out1)
fe_clear_vec([]^Montgomery_Domain_Field_Element{&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &xx})
}

View File

@@ -40,7 +40,7 @@ sc_zero :: proc {
p384r1.fe_zero,
}
sc_one_p256r1 :: proc {
sc_one :: proc {
p256r1.fe_one,
p384r1.fe_one,
}
@@ -70,6 +70,11 @@ sc_square :: proc {
p384r1.fe_square,
}
sc_inv :: proc {
p256r1.fe_inv,
p384r1.fe_inv,
}
sc_cond_assign :: proc {
p256r1.fe_cond_assign,
p384r1.fe_cond_assign,

View File

@@ -1,5 +1,6 @@
package test_core_crypto
import "core:crypto"
import ec "core:crypto/_weierstrass"
import "core:encoding/hex"
import "core:math/big"
@@ -881,7 +882,7 @@ test_p384_scalar_mul :: proc(t: ^testing.T) {
}
@(test)
test_p256_s11n_sec_identity ::proc(t: ^testing.T) {
test_p256_s11n_sec_identity :: proc(t: ^testing.T) {
p: ec.Point_p256r1
ec.pt_generator(&p)
@@ -901,7 +902,7 @@ test_p256_s11n_sec_identity ::proc(t: ^testing.T) {
}
@(test)
test_p256_s11n_sec_generator ::proc(t: ^testing.T) {
test_p256_s11n_sec_generator :: proc(t: ^testing.T) {
p, g: ec.Point_p256r1
ec.pt_generator(&g)
@@ -917,3 +918,33 @@ test_p256_s11n_sec_generator ::proc(t: ^testing.T) {
testing.expectf(t, ok, "%s", s)
testing.expect(t, ec.pt_equal(&g, &p) == 1)
}
@(test)
test_p256_sc_inv :: proc(t: ^testing.T) {
if crypto.HAS_RAND_BYTES == false {
return
}
sc, sc_inv, sc_prod, sc_one: ec.Scalar_p256r1
ec.sc_set_random(&sc)
ec.sc_inv(&sc_inv, &sc)
ec.sc_one(&sc_one)
ec.sc_mul(&sc_prod, &sc, &sc_inv)
testing.expect(t, ec.sc_equal(&sc_prod, &sc_one) == 1)
}
@(test)
test_p384_sc_inv :: proc(t: ^testing.T) {
if crypto.HAS_RAND_BYTES == false {
return
}
sc, sc_inv, sc_prod, sc_one: ec.Scalar_p384r1
ec.sc_set_random(&sc)
ec.sc_inv(&sc_inv, &sc)
ec.sc_one(&sc_one)
ec.sc_mul(&sc_prod, &sc, &sc_inv)
testing.expect(t, ec.sc_equal(&sc_prod, &sc_one) == 1)
}