mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 13:39:25 +00:00
71 lines
2.2 KiB
Rust
71 lines
2.2 KiB
Rust
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
|
#![doc = include_str!("../README.md")]
|
|
#![cfg_attr(not(feature = "std"), no_std)]
|
|
|
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
|
use std_shims::io::{self, Read};
|
|
|
|
use generic_array::typenum::{Sum, Diff, Quot, U, U1, U2};
|
|
use ciphersuite::group::{ff::PrimeField, Group};
|
|
|
|
#[macro_use]
|
|
mod backend;
|
|
|
|
mod scalar;
|
|
pub use scalar::Scalar;
|
|
|
|
pub use k256::Scalar as FieldElement;
|
|
|
|
mod point;
|
|
pub use point::Point;
|
|
|
|
/// Ciphersuite for Secq256k1.
|
|
///
|
|
/// hash_to_F is implemented with a naive concatenation of the dst and data, allowing transposition
|
|
/// between the two. This means `dst: b"abc", data: b"def"`, will produce the same scalar as
|
|
/// `dst: "abcdef", data: b""`. Please use carefully, not letting dsts be substrings of each other.
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, zeroize::Zeroize)]
|
|
pub struct Secq256k1;
|
|
impl ciphersuite::Ciphersuite for Secq256k1 {
|
|
type F = Scalar;
|
|
type G = Point;
|
|
type H = blake2::Blake2b512;
|
|
|
|
const ID: &'static [u8] = b"secq256k1";
|
|
|
|
fn generator() -> Self::G {
|
|
Point::generator()
|
|
}
|
|
|
|
fn reduce_512(scalar: [u8; 64]) -> Self::F {
|
|
Scalar::wide_reduce(scalar)
|
|
}
|
|
|
|
fn hash_to_F(dst: &[u8], data: &[u8]) -> Self::F {
|
|
use blake2::Digest;
|
|
Scalar::wide_reduce(Self::H::digest([dst, data].concat()).as_slice().try_into().unwrap())
|
|
}
|
|
|
|
// We override the provided impl, which compares against the reserialization, because
|
|
// we already require canonicity
|
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
|
#[allow(non_snake_case)]
|
|
fn read_G<R: Read>(reader: &mut R) -> io::Result<Self::G> {
|
|
use ciphersuite::group::GroupEncoding;
|
|
|
|
let mut encoding = <Self::G as GroupEncoding>::Repr::default();
|
|
reader.read_exact(encoding.as_mut())?;
|
|
|
|
let point = Option::<Self::G>::from(Self::G::from_bytes(&encoding))
|
|
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point"))?;
|
|
Ok(point)
|
|
}
|
|
}
|
|
|
|
impl generalized_bulletproofs_ec_gadgets::DiscreteLogParameters for Secq256k1 {
|
|
type ScalarBits = U<{ Scalar::NUM_BITS as usize }>;
|
|
type XCoefficients = Quot<Sum<Self::ScalarBits, U1>, U2>;
|
|
type XCoefficientsMinusOne = Diff<Self::XCoefficients, U1>;
|
|
type YxCoefficients = Diff<Quot<Sum<Sum<Self::ScalarBits, U1>, U1>, U2>, U2>;
|
|
}
|