mirror of https://github.com/gtank/ristretto255
internal/radix51: add constant time field operations
This commit is contained in:
parent
7ec609da40
commit
fe6e0954e0
1
LICENSE
1
LICENSE
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue