25519P = big_exp( 02, hex(255) )
25519p = big_sub( $25519p, hex(19))
// d = -121665/121666
tmp = hex(121665)
tmp = big_sub( $25519p, $tmp )
tmp1 = hex(121666)
tmp1 = big_mod_inv( $tmp1, $25519p )
curve25519_d = big_mod_mul( $tmp, $tmp1, $25519p )
bx = 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A
by = 6666666666666666666666666666666666666666666666666666666666666658
bz = 0000000000000000 0000000000000000 0000000000000000 0000000000000001
// t = x * y / z
bt = big_mod_mul( $bx, $by, $25519p )
k = 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
k = sha512_hash( $k )
k = left( $k, 32 )
k = memand( $k, 00, f8 )
k = memand( $k, 1f, 3f )
k = memor( $k, 1f, 40 )
clear_fifo
// k = 0000000000000000 0000000000000000 0000000000000000 0000000000000003
prompt off
call kp( $k, $bx, $by, $bz, $bt )
prompt on
rx = read_fifo
ry = read_fifo
rz = read_fifo
rt = read_fifo
t = call compressp( $rx, $ry, $rz )
t = reverse_block_byte( $t )
end
kp:
inputk = getpara
px = getpara
py = getpara
pz = getpara
pt = getpara
qx = 0000000000000000 0000000000000000 0000000000000000 0000000000000000
qy = 0000000000000000 0000000000000000 0000000000000000 0000000000000001
qz = 0000000000000000 0000000000000000 0000000000000000 0000000000000001
qt = 0000000000000000 0000000000000000 0000000000000000 0000000000000000
// ? "第一种写法, 从右向左扫描"
// inputk = reverse_block_byte( $inputk )
// again:
// if $inputk > 00
// bit = getbit_right( $inputk, 1f, 00, 00 )
// if $bit == 01
// clear_fifo
// call addp( $qx, $qy, $qz, $qt, $px, $py, $pz, $pt )
// qx = read_fifo
// qy = read_fifo
// qz = read_fifo
// qt = read_fifo
// endif
// clear_fifo
// call addp( $px, $py, $pz, $pt, $px, $py, $pz, $pt )
// px = read_fifo
// py = read_fifo
// pz = read_fifo
// pt = read_fifo
// inputk = shr( $inputk, 01 )
// else
// goto out
// endif
// goto again
// out:
? "第二种写法,从右到左扫描,没有移位操作"
flag = 00
hfor i = ff to 00 step -01
byte_off = div( $i, 08 )
bit_off = mod( $i, 08 )
//bit_off = sub( 07, $bit_off )
bit = getbit_right( $inputk, $byte_off, $bit_off, $bit_off )
if $bit == 01
flag = 01
endif
if $flag == 01
clear_fifo
call addp( $qx, $qy, $qz, $qt, $qx, $qy, $qz, $qt )
qx = read_fifo
qy = read_fifo
qz = read_fifo
qt = read_fifo
if $bit == 01
clear_fifo
call addp( $qx, $qy, $qz, $qt, $px, $py, $pz, $pt )
qx = read_fifo
qy = read_fifo
qz = read_fifo
qt = read_fifo
endif
endif
hnext i
clear_fifo
write_fifo $qx
write_fifo $qy
write_fifo $qz
write_fifo $qt
return
doublep:
x1 = getpara
y1 = getpara
z1 = getpara
t1 = getpara
// a = x1^2
a = big_mod_mul( $x1, $x1, $25519p )
a = leftpack( $a, 32 )
// b = y1^2
b = big_mod_mul( $y1, $y1, $25519p )
b = leftpack( $b, 32 )
// c = 2*z1^2
c = big_mod_mul( $z1, $z1, $25519p )
c = leftpack( $c, 32 )
c = big_mod_add( $c, $c, $25519p )
c = leftpack( $c, 32 )
// h = a + b
h = big_mod_add( $a, $b, $25519p )
h = leftpack( $h, 32 )
// e = h - (X1 + Y1)^2
e = big_mod_add( $x1, $y1, $25519p )
e = leftpack( $e, 32 )
e = big_mod_mul( $e, $e, $25519p )
e = leftpack( $e, 32 )
e = big_mod_sub( $h, $e, $25519p )
e = leftpack( $e, 32 )
// g = a - b
g = big_mod_sub( $a, $b, $25519p )
g = leftpack( $g, 32 )
// h = c + g
h = big_mod_add( $c, $g, $25519p )
h = leftpack( $h, 32 )
// x3 = e * f
x3 = big_mod_mul( $e, $f, $25519p )
x3 = leftpack( $x3, 32 )
// y3 = g * h
y3 = big_mod_mul( $g, $h, $25519p )
y3 = leftpack( $y3, 32 )
// t3 = e * h
t3 = big_mod_mul( $e, $h, $25519p )
t3 = leftpack( $t3, 32 )
// z3 = f * g
z3 = big_mod_mul( $f, $g, $25519p )
z3 = leftpack( $z3, 32 )
clear_fifo
write_fifo $x3
write_fifo $y3
write_fifo $z3
write_fifo $t3
return
addp:
x1 = getpara
y1 = getpara
z1 = getpara
t1 = getpara
x2 = getpara
y2 = getpara
z2 = getpara
t2 = getpara
// a = (y1-x1)*(y2-x2)
c = big_mod_sub( $y1, $x1, $25519p )
c = leftpack( $c, 32 )
d = big_mod_sub( $y2, $x2, $25519p )
d = leftpack( $d, 32 )
a = big_mod_mul( $c, $d, $25519p )
a = leftpack( $a, 32 )
// B = (Y1 + X1) * (Y2 + X2)
c = big_mod_add( $y1, $x1, $25519p )
c = leftpack( $c, 32 )
d = big_mod_add( $y2, $x2, $25519p )
d = leftpack( $d, 32 )
b = big_mod_mul( $c, $d, $25519p )
b = leftpack( $b, 32 )
// C = t1*2*d*t2
c = big_mod_mul( $t1, 02, $25519p )
c = leftpack( $c, 32 )
c = big_mod_mul( $c, $curve25519_d, $25519p )
c = leftpack( $c, 32 )
c = big_mod_mul( $c, $t2, $25519p )
c = leftpack( $c, 32 )
// d =z1 *2 * z2
d = big_mod_mul( $z1, $z2, $25519p )
d = leftpack( $d, 32 )
d = big_mod_mul( $d, 02, $25519p )
d = leftpack( $d, 32 )
// e = b-a
e = big_mod_sub( $b, $a, $25519p )
e = leftpack( $e, 32 )
// f = d - c
f = big_mod_sub( $d, $c, $25519p )
f = leftpack( $f, 32 )
// g = d + c
g = big_mod_add( $d, $c, $25519p )
g = leftpack( $g, 32 )
// h = b + a
h = big_mod_add( $b, $a, $25519p )
h = leftpack( $h, 32 )
// x3 = e*f
x3 = big_mod_mul( $e, $f, $25519p )
x3 = leftpack( $x3, 32 )
// y3 = g*h
y3 = big_mod_mul( $g, $h, $25519p )
y3 = leftpack( $y3, 32 )
// z3 = f*g
z3 = big_mod_mul( $f, $g, $25519p )
z3 = leftpack( $z3, 32 )
// t3 = e*h
t3 = big_mod_mul( $e, $h, $25519p )
t3 = leftpack( $t3, 32 )
// ? "point add"
// ? "a = " $a
// ? "b = " $b
// ? "c = " $c
// ? "d = " $d
// ? "e = " $e
// ? "f = " $f
// ? "g = " $g
// ? "h = " $h
// ? "x3 = " $x3
// ? "y3 = " $y3
// ? "z3 = " $z3
// ? "t3 = " $t3
clear_fifo
write_fifo $x3
write_fifo $y3
write_fifo $z3
write_fifo $t3
return
compressp:
inx = getpara
iny = getpara
inz = getpara
zinv = big_mod_inv( $inz, $25519p )
x = big_mod_mul( $inz, $zinv, $25519p )
if $x != 00000001
?
pause
endif
tmpx = big_mod_mul( $inx, $zinv, $25519p )
tmpy = big_mod_mul( $iny, $zinv, $25519p )
bit = getbit_right( $tmpx, 1f, 00, 00 )
bit = shl( $bit, 255 )
tmpy = or( $tmpy, $bit )
return $tmpy