Implement traits required by multiexp

This commit is contained in:
Daniel Tehrani
2023-01-16 13:30:02 +09:00
parent 39fd062aef
commit f374ee0661
3 changed files with 131 additions and 6 deletions

View File

@@ -13,3 +13,5 @@ serde = { version = "1.0.106", features = ["derive"] }
rand_core = { version = "0.6", default-features = false }
zeroize = { version = "1", default-features = false }
k256 = "0.11.6"
ff = "0.12.0"

View File

@@ -1,7 +1,11 @@
use std::ops::{Add, Mul, Sub};
use std::iter::Sum;
use std::ops::{Add, Mul, MulAssign, Neg, Sub};
use std::ops::{AddAssign, SubAssign};
use super::{ProjectivePoint, Secq256K1};
use crate::{EncodedPoint, Scalar};
use k256::elliptic_curve::subtle::Choice;
use primeorder::elliptic_curve::group::Group;
use primeorder::elliptic_curve::sec1::FromEncodedPoint;
use primeorder::elliptic_curve::sec1::ToEncodedPoint;
use primeorder::elliptic_curve::subtle::CtOption;
@@ -27,6 +31,26 @@ impl Mul<Scalar> for &AffinePoint {
}
}
impl Mul<&Scalar> for AffinePoint {
type Output = AffinePoint;
fn mul(self, rhs: &Scalar) -> Self::Output {
AffinePoint((self.0 * *rhs).into())
}
}
impl MulAssign<&Scalar> for AffinePoint {
fn mul_assign(&mut self, rhs: &Scalar) {
*self = *self * rhs;
}
}
impl MulAssign<Scalar> for AffinePoint {
fn mul_assign(&mut self, rhs: Scalar) {
*self = *self * rhs;
}
}
impl Add<AffinePoint> for AffinePoint {
type Output = AffinePoint;
@@ -35,6 +59,12 @@ impl Add<AffinePoint> for AffinePoint {
}
}
impl AddAssign<AffinePoint> for AffinePoint {
fn add_assign(&mut self, rhs: AffinePoint) {
*self = *self + rhs;
}
}
impl Sub<AffinePoint> for AffinePoint {
type Output = AffinePoint;
@@ -43,6 +73,12 @@ impl Sub<AffinePoint> for AffinePoint {
}
}
impl SubAssign<AffinePoint> for AffinePoint {
fn sub_assign(&mut self, rhs: AffinePoint) {
*self = *self - rhs;
}
}
impl AffinePoint {
pub fn identity() -> Self {
AffinePoint(AffinePointCore::IDENTITY)
@@ -66,3 +102,75 @@ impl From<ProjectivePoint> for AffinePoint {
AffinePoint(p.into())
}
}
impl Neg for AffinePoint {
type Output = AffinePoint;
fn neg(self) -> Self::Output {
AffinePoint(self.0.neg())
}
}
impl Add<&AffinePoint> for AffinePoint {
type Output = AffinePoint;
fn add(self, rhs: &AffinePoint) -> Self::Output {
self + *rhs
}
}
impl AddAssign<&AffinePoint> for AffinePoint {
fn add_assign(&mut self, rhs: &AffinePoint) {
*self = *self + *rhs;
}
}
impl Sub<&AffinePoint> for AffinePoint {
type Output = AffinePoint;
fn sub(self, rhs: &AffinePoint) -> Self::Output {
self - *rhs
}
}
impl SubAssign<&AffinePoint> for AffinePoint {
fn sub_assign(&mut self, rhs: &AffinePoint) {
*self = *self - *rhs;
}
}
impl Sum for AffinePoint {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(AffinePoint::identity(), |acc, x| acc + x)
}
}
impl<'a> Sum<&'a AffinePoint> for AffinePoint {
fn sum<I: Iterator<Item = &'a AffinePoint>>(iter: I) -> Self {
iter.fold(AffinePoint::identity(), |acc, x| acc + x)
}
}
impl Group for AffinePoint {
type Scalar = Scalar;
fn random(rng: impl rand_core::RngCore) -> Self {
AffinePoint(AffinePointCore::from(ProjectivePoint::random(rng)))
}
fn generator() -> Self {
AffinePoint::generator()
}
fn identity() -> Self {
AffinePoint::identity()
}
fn is_identity(&self) -> Choice {
self.0.is_identity()
}
fn double(&self) -> Self {
self.add(self)
}
}

View File

@@ -2,6 +2,8 @@ use crate::field::field_secp::FieldElement;
use super::{FieldBytes, Secq256K1};
use ff::{Field, PrimeField, PrimeFieldBits};
use k256::elliptic_curve::bigint::Encoding;
use primeorder::elliptic_curve::{
bigint::{Limb, U256},
generic_array::arr,
@@ -9,7 +11,7 @@ use primeorder::elliptic_curve::{
rand_core::RngCore,
subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
zeroize::DefaultIsZeroes,
Curve, Error, Field, IsHigh, PrimeField, Result,
Curve, Error, IsHigh, Result,
};
use std::{
@@ -23,14 +25,14 @@ type ScalarCore = primeorder::elliptic_curve::ScalarCore<Secq256K1>;
pub struct Scalar(pub ScalarCore);
impl Field for Scalar {
fn zero() -> Self {
Self(ScalarCore::ZERO)
}
fn one() -> Self {
Self(ScalarCore::ONE)
}
fn zero() -> Self {
Self(ScalarCore::ZERO)
}
fn random(mut rng: impl RngCore) -> Self {
let mut bytes = FieldBytes::default();
@@ -97,6 +99,7 @@ impl PrimeField for Scalar {
.unwrap()
}
}
impl DefaultIsZeroes for Scalar {}
impl ConstantTimeEq for Scalar {
@@ -298,6 +301,18 @@ impl From<u32> for Scalar {
}
}
impl PrimeFieldBits for Scalar {
type ReprBits = [u8; 32];
fn to_le_bits(&self) -> ff::FieldBits<Self::ReprBits> {
self.to_bytes().into()
}
fn char_le_bits() -> ff::FieldBits<Self::ReprBits> {
ScalarCore::MODULUS.to_be_bytes().into()
}
}
#[cfg(test)]
mod tests {
use super::*;