@@ -12,12 +12,12 @@ import ( | |||
// Set result to zero if the input scalar is <= 3^238. scalar must be 48-byte array | |||
// of bytes. This function is specific to P751. | |||
//go:noescape | |||
func checkLessThanThree238(scalar *byte, result *uint32) | |||
func checkLessThanThree238(scalar []byte) uint64 | |||
// Multiply 48-byte scalar by 3 to get a scalar in 3*[0,3^238). This | |||
// function is specific to P751. | |||
//go:noescape | |||
func multiplyByThree(scalar *byte) | |||
func multiplyByThree(scalar []byte) | |||
// ----------------------------------------------------------------------------- | |||
// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is | |||
@@ -196,7 +196,7 @@ func (prv *PrivateKey) generatePrivateKeyA(rand io.Reader) error { | |||
// shared secret computation. | |||
func (prv *PrivateKey) generatePrivateKeyB(rand io.Reader) error { | |||
// Perform rejection sampling to obtain a random value in [0,3^238]: | |||
var ok uint32 | |||
var ok uint64 | |||
for i := uint(0); i < prv.params.SampleRate; i++ { | |||
_, err := io.ReadFull(rand, prv.Scalar) | |||
if err != nil { | |||
@@ -209,7 +209,7 @@ func (prv *PrivateKey) generatePrivateKeyB(rand io.Reader) error { | |||
// Accept if scalar < 3^238 (this happens w/ prob ~0.5828) | |||
// TODO this is specific to P751 | |||
checkLessThanThree238(&prv.Scalar[0], &ok) | |||
ok = checkLessThanThree238(prv.Scalar) | |||
if ok == 0 { | |||
break | |||
} | |||
@@ -223,7 +223,7 @@ func (prv *PrivateKey) generatePrivateKeyB(rand io.Reader) error { | |||
} | |||
// Multiply by 3 to get a scalar in 3*[0,3^238): | |||
multiplyByThree(&prv.Scalar[0]) | |||
multiplyByThree(prv.Scalar) | |||
// We actually want scalar in 2*(0,2^371), but the above procedure | |||
// generates 0 with probability 2^(-371), which isn't worth checking | |||
// for. | |||
@@ -1,3 +1,5 @@ | |||
// +build amd64,!noasm | |||
#include "textflag.h" | |||
// Digits of 3^238 - 1 | |||
@@ -10,9 +12,9 @@ | |||
// Set result to zero if the input scalar is <= 3^238. scalar must be 48-byte array | |||
// of bytes. | |||
// func checkLessThanThree238(s_base uintptr, s_len uint, s_cap uint) uint64 | |||
TEXT ·checkLessThanThree238(SB), NOSPLIT, $0-16 | |||
MOVQ scalar+0(FP), SI | |||
MOVQ result+8(FP), DI | |||
XORQ AX, AX | |||
@@ -25,16 +27,16 @@ TEXT ·checkLessThanThree238(SB), NOSPLIT, $0-16 | |||
MOVQ THREE238M1_5, R15 | |||
// Set [R10,...,R15] = 3^238 - scalar | |||
SUBQ (SI), R10 | |||
SBBQ (8)(SI), R11 | |||
SBBQ (16)(SI), R12 | |||
SBBQ (24)(SI), R13 | |||
SBBQ (32)(SI), R14 | |||
SBBQ (40)(SI), R15 | |||
SUBQ (SI), R10 | |||
SBBQ 8(SI), R11 | |||
SBBQ 16(SI), R12 | |||
SBBQ 24(SI), R13 | |||
SBBQ 32(SI), R14 | |||
SBBQ 40(SI), R15 | |||
// Save borrow flag indicating 3^238 - scalar < 0 as a mask in AX (eax) | |||
SBBL $0, AX | |||
MOVL AX, (DI) | |||
MOVL AX, ret+24(FP) | |||
RET | |||
@@ -43,12 +45,12 @@ TEXT ·multiplyByThree(SB), NOSPLIT, $0-8 | |||
MOVQ scalar+0(FP), SI | |||
// Set [R10,...,R15] = scalar | |||
MOVQ (SI), R10 | |||
MOVQ (8)(SI), R11 | |||
MOVQ (16)(SI), R12 | |||
MOVQ (24)(SI), R13 | |||
MOVQ (32)(SI), R14 | |||
MOVQ (40)(SI), R15 | |||
MOVQ (SI), R10 | |||
MOVQ 8(SI), R11 | |||
MOVQ 16(SI), R12 | |||
MOVQ 24(SI), R13 | |||
MOVQ 32(SI), R14 | |||
MOVQ 40(SI), R15 | |||
// Add scalar twice to compute 3*scalar | |||
ADDQ R10, (SI) | |||
@@ -236,7 +236,7 @@ func TestMultiplyByThree(t *testing.T) { | |||
135, 190, 110, 125, 134, 233, 132, 128, 116, 37, 203, 69, 80, 43, 86, 104, 198, 173, | |||
123, 249, 9, 41, 225, 192, 113, 31, 84, 93, 254, 6} | |||
multiplyByThree(&three238minus1[0]) | |||
multiplyByThree(three238minus1[:]) | |||
for i := 0; i < 48; i++ { | |||
if three238minus1[i] != threeTimesThree238minus1[i] { | |||
@@ -260,17 +260,17 @@ func TestCheckLessThanThree238(t *testing.T) { | |||
153, 108, 197, 99, 199, 34, 66, 143, 126, 168, 88, 184, 245, 234, 37, 181, 198, | |||
201, 84, 2} | |||
var result = uint32(57) | |||
var result uint64 | |||
checkLessThanThree238(&three238minus1[0], &result) | |||
result = checkLessThanThree238(three238minus1[:]) | |||
if result != 0 { | |||
t.Error("expected 0, got", result) | |||
} | |||
checkLessThanThree238(&three238[0], &result) | |||
result = checkLessThanThree238(three238[:]) | |||
if result == 0 { | |||
t.Error("expected nonzero, got", result) | |||
} | |||
checkLessThanThree238(&three238plus1[0], &result) | |||
result = checkLessThanThree238(three238plus1[:]) | |||
if result == 0 { | |||
t.Error("expected nonzero, got", result) | |||
} | |||