Files
Odin/core/crypto/_weierstrass/sc.odin
2026-02-20 04:10:54 +09:00

143 lines
2.4 KiB
Odin

package _weierstrass
@(require) import "core:crypto"
import p256r1 "core:crypto/_fiat/field_scalarp256r1"
import p384r1 "core:crypto/_fiat/field_scalarp384r1"
import subtle "core:crypto/_subtle"
Scalar_p256r1 :: p256r1.Montgomery_Domain_Field_Element
Scalar_p384r1 :: p384r1.Montgomery_Domain_Field_Element
SC_SIZE_P256R1 :: 32
SC_SIZE_P384R1 :: 48
SC_SIZE_MAX :: SC_SIZE_P384R1
sc_size :: proc "contextless" (sc: ^$T) -> int where T == Scalar_p256r1 || T == Scalar_p384r1 {
when T == Scalar_p256r1 {
return SC_SIZE_P256R1
} else when T == Scalar_p384r1 {
return SC_SIZE_P384R1
}
}
sc_set_random :: proc(sc: ^$T) where T == Scalar_p256r1 || T == Scalar_p384r1 {
ensure(crypto.HAS_RAND_BYTES, "weierstrass: entropy source required")
b: [48]byte = ---
defer crypto.zero_explicit(&b, size_of(b))
when T == Scalar_p256r1 {
// 384-bits reduced makes the modulo bias insignificant
for {
crypto.rand_bytes(b[:])
_ = sc_set_bytes(sc, b[:])
if sc_is_zero(sc) == 0 { // Likely
break
}
}
} else when T == Scalar_p384r1 {
for {
crypto.rand_bytes(b[:])
did_reduce := sc_set_bytes(sc, b[:])
if !did_reduce && sc_is_zero(sc) == 0 { // Likely
break
}
}
}
}
sc_clear :: proc {
p256r1.fe_clear,
p384r1.fe_clear,
}
sc_clear_vec :: proc {
p256r1.fe_clear_vec,
p384r1.fe_clear_vec,
}
sc_set_bytes :: proc {
p256r1.fe_from_bytes,
p384r1.fe_from_bytes,
}
sc_bytes :: proc {
p256r1.fe_to_bytes,
p384r1.fe_to_bytes,
}
sc_set :: proc {
p256r1.fe_set,
p384r1.fe_set,
}
sc_zero :: proc {
p256r1.fe_zero,
p384r1.fe_zero,
}
sc_one :: proc {
p256r1.fe_one,
p384r1.fe_one,
}
sc_add :: proc {
p256r1.fe_add,
p384r1.fe_add,
}
sc_sub :: proc {
p256r1.fe_sub,
p384r1.fe_sub,
}
sc_negate :: proc {
p256r1.fe_opp,
p384r1.fe_opp,
}
sc_mul :: proc {
p256r1.fe_mul,
p384r1.fe_mul,
}
sc_square :: proc {
p256r1.fe_square,
p384r1.fe_square,
}
sc_inv :: proc {
p256r1.fe_inv,
p384r1.fe_inv,
}
sc_cond_assign :: proc {
p256r1.fe_cond_assign,
p384r1.fe_cond_assign,
}
sc_equal :: proc {
p256r1.fe_equal,
p384r1.fe_equal,
}
sc_is_odd :: proc {
p256r1.fe_is_odd,
p384r1.fe_is_odd,
}
sc_is_zero :: proc {
sc_is_zero_p256r1,
sc_is_zero_p384r1,
}
@(require_results)
sc_is_zero_p256r1 :: proc "contextless" (fe: ^Scalar_p256r1) -> int {
return int(subtle.u64_is_zero(p256r1.fe_non_zero(fe)))
}
@(require_results)
sc_is_zero_p384r1 :: proc "contextless" (fe: ^Scalar_p384r1) -> int {
return int(subtle.u64_is_zero(p384r1.fe_non_zero(fe)))
}