mod ristretto;
mod sec2;
pub use self::ristretto::*;
pub use self::sec2::*;
use core::marker::PhantomData;
use cryptoxide::drg::chacha;
use cryptoxide::hashing::sha2;
use eccoxide::curve::field::Field;
use eccoxide::curve::group::CurveGroup;
use std::ops::{Add, Mul, Sub};
pub struct Drg(chacha::Drg<8>);
impl Drg {
pub fn new() -> Self {
loop {
let mut out = [0u8; 32];
if let Err(_) = getrandom::fill(&mut out) {
continue;
}
let drg = chacha::Drg::new(&out);
return Drg(drg);
}
}
}
pub trait Transcript {
type Scalar;
fn new() -> Self;
fn new_sep(label: &[u8]) -> Self;
fn absorb(&mut self, bytes: &[u8]);
fn challenge(self) -> Self::Scalar;
}
pub trait TranscriptHash {
type Context;
fn init() -> Self::Context;
fn absorb(context: &mut Self::Context, bytes: &[u8]);
fn finalize(context: Self::Context) -> Vec<u8>;
}
pub enum Sha256 {}
impl TranscriptHash for Sha256 {
type Context = sha2::Context256;
fn init() -> Self::Context {
sha2::Context256::new()
}
fn absorb(context: &mut Self::Context, bytes: &[u8]) {
context.update_mut(bytes);
}
fn finalize(context: Self::Context) -> Vec<u8> {
context.finalize().to_vec()
}
}
pub enum Sha512 {}
impl TranscriptHash for Sha512 {
type Context = sha2::Context512;
fn init() -> Self::Context {
sha2::Context512::new()
}
fn absorb(context: &mut Self::Context, bytes: &[u8]) {
context.update_mut(bytes);
}
fn finalize(context: Self::Context) -> Vec<u8> {
context.finalize().to_vec()
}
}
pub(crate) fn hash_expand<H: TranscriptHash>(parts: &[&[u8]], out: &mut [u8]) {
let mut block: u32 = 0;
let mut off = 0;
while off < out.len() {
let mut context = H::init();
for p in parts {
H::absorb(&mut context, p);
}
H::absorb(&mut context, &block.to_be_bytes());
let digest = H::finalize(context);
let n = core::cmp::min(digest.len(), out.len() - off);
out[off..off + n].copy_from_slice(&digest[..n]);
off += n;
block = block.wrapping_add(1);
}
}
pub struct HashTranscript<C: EcOperation, H: TranscriptHash> {
context: H::Context,
_curve: PhantomData<C>,
}
impl<C: EcOperation, H: TranscriptHash> Transcript for HashTranscript<C, H> {
type Scalar = C::Scalar;
fn new() -> Self {
HashTranscript {
context: H::init(),
_curve: PhantomData,
}
}
fn new_sep(label: &[u8]) -> Self {
let mut context = H::init();
H::absorb(&mut context, label);
HashTranscript {
context,
_curve: PhantomData,
}
}
fn absorb(&mut self, bytes: &[u8]) {
H::absorb(&mut self.context, bytes);
}
fn challenge(self) -> C::Scalar {
let seed = H::finalize(self.context);
let mut buf = vec![0u8; 2 * C::SCALAR_BYTES];
hash_expand::<H>(&[&seed], &mut buf);
C::scalar_from_wide_bytes(&buf)
}
}
pub trait EcOperation: Clone {
type Scalar: Field;
type Point: CurveGroup<Scalar = Self::Scalar>;
type Transcript: Transcript<Scalar = Self::Scalar>;
const SCALAR_BYTES: usize;
fn scalar_from_bytes(bytes: &[u8]) -> Option<Self::Scalar>;
fn scalar_from_wide_bytes(bytes: &[u8]) -> Self::Scalar;
fn scalar_to_bytes(s: &Self::Scalar) -> Vec<u8>;
fn point_to_bytes(p: &Self::Point) -> Vec<u8>;
fn point_from_bytes(bytes: &[u8]) -> Option<Self::Point>;
fn point_try_hash_to_curve(data: &[u8]) -> Option<Self::Point>;
fn point_hash_to_curve(data: &[u8]) -> Self::Point;
}
pub struct Scalar<C: EcOperation> {
inner: C::Scalar,
}
impl<C: EcOperation> Clone for Scalar<C> {
fn clone(&self) -> Self {
Scalar {
inner: self.inner.clone(),
}
}
}
impl<C: EcOperation> PartialEq for Scalar<C> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl<C: EcOperation> Scalar<C> {
pub fn from_u32(v: u32) -> Scalar<C> {
Scalar {
inner: C::Scalar::from(v as u64),
}
}
pub fn generate(drg: &mut Drg) -> Scalar<C> {
let mut buf = vec![0u8; 2 * C::SCALAR_BYTES];
drg.0.fill_slice(&mut buf);
Scalar {
inner: C::scalar_from_wide_bytes(&buf),
}
}
pub fn multiplicative_identity() -> Scalar<C> {
Self::from_u32(1)
}
pub fn hash_points(points: Vec<&Point<C>>) -> Scalar<C> {
let mut hasher = PointHasher::<C>::new();
for p in points {
hasher.update_mut(p);
}
hasher.finalize()
}
pub fn pow(&self, pow: u32) -> Scalar<C> {
let mut result = C::Scalar::ONE;
let mut base = self.inner.clone();
let mut exp = pow;
while exp > 0 {
if exp & 1 == 1 {
result = result * &base;
}
exp >>= 1;
if exp > 0 {
base = base.square();
}
}
Scalar { inner: result }
}
pub fn inverse(&self) -> Scalar<C> {
Scalar {
inner: self.inner.inverse(),
}
}
pub fn from_bytes(bytes: &[u8]) -> Option<Scalar<C>> {
C::scalar_from_bytes(bytes).map(|inner| Scalar { inner })
}
pub fn to_bytes(&self) -> Vec<u8> {
C::scalar_to_bytes(&self.inner)
}
}
impl<C: EcOperation> Add for Scalar<C> {
type Output = Scalar<C>;
fn add(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner + s.inner,
}
}
}
impl<'a, C: EcOperation> Add for &'a Scalar<C> {
type Output = Scalar<C>;
fn add(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner.clone() + &s.inner,
}
}
}
impl<C: EcOperation> Sub for Scalar<C> {
type Output = Scalar<C>;
fn sub(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner - s.inner,
}
}
}
impl<'a, C: EcOperation> Sub for &'a Scalar<C> {
type Output = Scalar<C>;
fn sub(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner.clone() - &s.inner,
}
}
}
impl<C: EcOperation> Mul for Scalar<C> {
type Output = Scalar<C>;
fn mul(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner * s.inner,
}
}
}
impl<'a, C: EcOperation> Mul for &'a Scalar<C> {
type Output = Scalar<C>;
fn mul(self, s: Self) -> Scalar<C> {
Scalar {
inner: self.inner.clone() * &s.inner,
}
}
}
pub struct Point<C: EcOperation> {
inner: C::Point,
}
impl<C: EcOperation> Clone for Point<C> {
fn clone(&self) -> Self {
Point {
inner: self.inner.clone(),
}
}
}
impl<C: EcOperation> PartialEq for Point<C> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl<C: EcOperation> Point<C> {
pub fn infinity() -> Point<C> {
Point {
inner: C::Point::IDENTITY,
}
}
pub fn generator() -> Point<C> {
Point {
inner: C::Point::GENERATOR,
}
}
pub fn try_hash_to_curve(slice: &[u8]) -> Option<Point<C>> {
C::point_try_hash_to_curve(slice).map(|inner| Point { inner })
}
pub fn hash_to_curve(slice: &[u8]) -> Point<C> {
Point {
inner: C::point_hash_to_curve(slice),
}
}
pub fn random_generator(drg: &mut Drg) -> Point<C> {
let mut seed = vec![0u8; 2 * C::SCALAR_BYTES];
loop {
drg.0.fill_slice(&mut seed);
if let Some(point) = Self::try_hash_to_curve(&seed) {
return point;
}
}
}
pub fn from_scalar(s: &Scalar<C>) -> Point<C> {
Point {
inner: C::Point::mul_base(&s.inner),
}
}
pub fn mul(&self, s: &Scalar<C>) -> Point<C> {
Point {
inner: self.inner.clone() * &s.inner,
}
}
pub fn inverse(&self) -> Point<C> {
Point {
inner: -self.inner.clone(),
}
}
pub fn from_bytes(slice: &[u8]) -> Option<Point<C>> {
C::point_from_bytes(slice).map(|inner| Point { inner })
}
pub fn to_bytes(&self) -> Vec<u8> {
C::point_to_bytes(&self.inner)
}
}
impl<C: EcOperation> Add for Point<C> {
type Output = Point<C>;
fn add(self, p: Self) -> Point<C> {
Point {
inner: self.inner + p.inner,
}
}
}
impl<C: EcOperation> Sub for Point<C> {
type Output = Point<C>;
fn sub(self, p: Self) -> Point<C> {
Point {
inner: self.inner - p.inner,
}
}
}
pub struct PointHasher<C: EcOperation> {
transcript: C::Transcript,
}
impl<C: EcOperation> PointHasher<C> {
pub fn new() -> Self {
PointHasher {
transcript: C::Transcript::new(),
}
}
pub fn new_sep(label: &[u8]) -> Self {
PointHasher {
transcript: C::Transcript::new_sep(label),
}
}
pub fn update_mut(&mut self, p: &Point<C>) {
self.transcript.absorb(&p.to_bytes());
}
pub fn update(mut self, p: &Point<C>) -> Self {
self.transcript.absorb(&p.to_bytes());
self
}
pub fn update_iter<'a, I: Iterator<Item = &'a Point<C>>>(mut self, it: I) -> Self
where
C: 'a,
{
for i in it {
self.transcript.absorb(&i.to_bytes());
}
self
}
pub fn finalize(self) -> Scalar<C> {
Scalar {
inner: self.transcript.challenge(),
}
}
}
pub struct PrivateKey<C: EcOperation> {
pub scalar: Scalar<C>,
}
pub struct PublicKey<C: EcOperation> {
pub point: Point<C>,
}
impl<C: EcOperation> Clone for PublicKey<C> {
fn clone(&self) -> Self {
PublicKey {
point: self.point.clone(),
}
}
}
impl<C: EcOperation> PartialEq for PublicKey<C> {
fn eq(&self, other: &Self) -> bool {
self.point == other.point
}
}
impl<C: EcOperation> PartialEq for PrivateKey<C> {
fn eq(&self, other: &Self) -> bool {
self.scalar == other.scalar
}
}
impl<C: EcOperation> PublicKey<C> {
pub fn to_bytes(&self) -> Vec<u8> {
self.point.to_bytes()
}
pub fn from_bytes(bytes: &[u8]) -> PublicKey<C> {
PublicKey {
point: Point::from_bytes(bytes).unwrap(),
}
}
}
impl<C: EcOperation> PrivateKey<C> {
pub fn to_bytes(&self) -> Vec<u8> {
self.scalar.to_bytes()
}
pub fn from_bytes(bytes: &[u8]) -> PrivateKey<C> {
PrivateKey {
scalar: Scalar::from_bytes(bytes).unwrap(),
}
}
}
pub fn create_keypair<C: EcOperation>(drg: &mut Drg) -> (PublicKey<C>, PrivateKey<C>) {
let s = Scalar::generate(drg);
let p = Point::from_scalar(&s);
(PublicKey { point: p }, PrivateKey { scalar: s })
}