internal/radix51: add constant time field operations

This commit is contained in:
Filippo Valsorda 2019-01-21 17:51:39 -05:00 committed by George Tankersley
parent 7ec609da40
commit fe6e0954e0
2 changed files with 49 additions and 0 deletions

View File

@ -1,4 +1,5 @@
Copyright 2017 George Tankersley. All rights reserved.
Copyright 2019 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

View File

@ -1,4 +1,5 @@
// Copyright (c) 2017 George Tankersley. All rights reserved.
// Copyright (c) 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@ -7,6 +8,7 @@
package radix51
import (
"crypto/subtle"
"math/big"
"math/bits"
)
@ -330,3 +332,49 @@ func FeToBig(h *FieldElement) *big.Int {
out := new(big.Int)
return out.SetBits(words)
}
// FeEqual returns 1 if a and b are equal, and 0 otherwise.
func FeEqual(a, b *FieldElement) int {
var sa, sb [32]byte
FeToBytes(&sa, a)
FeToBytes(&sb, b)
return subtle.ConstantTimeCompare(sa[:], sb[:])
}
// FeSelect sets out to v if cond == 1, and to u if cond == 0.
// out, v and u are allowed to overlap.
func FeSelect(out, v, u *FieldElement, cond int) {
b := uint64(cond) * 0xffffffffffffffff
out[0] = (b & v[0]) | (^b & u[0])
out[1] = (b & v[1]) | (^b & u[1])
out[2] = (b & v[2]) | (^b & u[2])
out[3] = (b & v[3]) | (^b & u[3])
out[4] = (b & v[4]) | (^b & u[4])
}
// FeCondNeg sets u to -u if cond == 1, and to u if cond == 0.
func FeCondNeg(u *FieldElement, cond int) {
var neg FieldElement
FeNeg(&neg, u)
b := uint64(cond) * 0xffffffffffffffff
u[0] ^= b & (u[0] ^ neg[0])
u[1] ^= b & (u[1] ^ neg[1])
u[2] ^= b & (u[2] ^ neg[2])
u[3] ^= b & (u[3] ^ neg[3])
u[4] ^= b & (u[4] ^ neg[4])
}
// FeIsNegative returns 1 if u is negative, and 0 otherwise.
func FeIsNegative(u *FieldElement) int {
var b [32]byte
FeToBytes(&b, u)
return int(b[0] & 1)
}
// FeAbs sets out to |u|. out and u are allowed to overlap.
func FeAbs(out, u *FieldElement) {
var neg FieldElement
FeNeg(&neg, u)
FeSelect(out, &neg, u, FeIsNegative(u))
}