secp256k1: Return num instead of bool for overflow.
This modifies the SetBytes method on the ModNScalar type to return the overflow condition as a uint32 instead of a bool in order to better facilite constant time code in upcoming changes and updates the callers as needed. It also updates the internal fieldToModNScalar convenience function to return the flag as well.
This commit is contained in:
parent
b21feec2cd
commit
3db614b5a4
@ -298,9 +298,13 @@ func (s *ModNScalar) reduce256(overflows uint32) {
|
||||
|
||||
// SetBytes interprets the provided array as a 256-bit big-endian unsigned
|
||||
// integer, reduces it modulo the group order, sets the scalar to the result,
|
||||
// and returns whether or not it was reduced (aka it overflowed) in constant
|
||||
// time.
|
||||
func (s *ModNScalar) SetBytes(b *[32]byte) bool {
|
||||
// and returns either 1 if it was reduced (aka it overflowed) or 0 otherwise in
|
||||
// constant time.
|
||||
//
|
||||
// Note that a bool is not used here because it is not possible in Go to convert
|
||||
// from a bool to numeric value in constant time and many constant-time
|
||||
// operations require a numeric value.
|
||||
func (s *ModNScalar) SetBytes(b *[32]byte) uint32 {
|
||||
// Pack the 256 total bits across the 8 uint32 words. This could be done
|
||||
// with a for loop, but benchmarks show this unrolled version is about 2
|
||||
// times faster than the variant that uses a loop.
|
||||
@ -317,7 +321,7 @@ func (s *ModNScalar) SetBytes(b *[32]byte) bool {
|
||||
// not it was reduced.
|
||||
needsReduce := s.overflows()
|
||||
s.reduce256(needsReduce)
|
||||
return needsReduce != 0
|
||||
return needsReduce
|
||||
}
|
||||
|
||||
// zeroArray32 zeroes the provided 32-byte buffer.
|
||||
@ -343,7 +347,7 @@ func (s *ModNScalar) SetByteSlice(b []byte) bool {
|
||||
copy(b32[32-len(b):], b)
|
||||
result := s.SetBytes(&b32)
|
||||
zeroArray32(&b32)
|
||||
return result
|
||||
return result != 0
|
||||
}
|
||||
|
||||
// PutBytes unpacks the scalar to a 32-byte big-endian value using the passed
|
||||
|
||||
@ -243,7 +243,7 @@ func TestModNScalarSetBytes(t *testing.T) {
|
||||
truncatedInBytes = truncatedInBytes[:32]
|
||||
}
|
||||
copy(b32[32-len(truncatedInBytes):], truncatedInBytes)
|
||||
overflow = s2.SetBytes(&b32)
|
||||
overflow = s2.SetBytes(&b32) != 0
|
||||
if !reflect.DeepEqual(s2.n, test.expected) {
|
||||
t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
|
||||
s2.n, test.expected)
|
||||
|
||||
@ -137,14 +137,20 @@ func (sig *Signature) Serialize() []byte {
|
||||
return b
|
||||
}
|
||||
|
||||
// fieldToModNScalar converts a field value to scalar modulo the curve order.
|
||||
func fieldToModNScalar(v *fieldVal) ModNScalar {
|
||||
// fieldToModNScalar converts a field value to scalar modulo the group order and
|
||||
// returns the scalar along with either 1 if it was reduced (aka it overflowed)
|
||||
// or 0 otherwise.
|
||||
//
|
||||
// Note that a bool is not used here because it is not possible in Go to convert
|
||||
// from a bool to numeric value in constant time and many constant-time
|
||||
// operations require a numeric value.
|
||||
func fieldToModNScalar(v *fieldVal) (ModNScalar, uint32) {
|
||||
var buf [32]byte
|
||||
v.PutBytes(&buf)
|
||||
var s ModNScalar
|
||||
s.SetBytes(&buf)
|
||||
overflow := s.SetBytes(&buf)
|
||||
zeroArray32(&buf)
|
||||
return s
|
||||
return s, overflow
|
||||
}
|
||||
|
||||
// Verify returns whether or not the signature is valid for the provided hash
|
||||
@ -223,7 +229,7 @@ func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
|
||||
// Note that the point must be in affine coordinates since R is in affine
|
||||
// coordinates.
|
||||
X.ToAffine()
|
||||
x := fieldToModNScalar(&X.x)
|
||||
x, _ := fieldToModNScalar(&X.x)
|
||||
|
||||
// Step 8.
|
||||
//
|
||||
@ -604,7 +610,7 @@ func signRFC6979(privateKey *PrivateKey, hash []byte) *Signature {
|
||||
//
|
||||
// r = kG.x mod N
|
||||
// Repeat from step 1 if r = 0
|
||||
r := fieldToModNScalar(&kG.x)
|
||||
r, _ := fieldToModNScalar(&kG.x)
|
||||
if r.IsZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user