All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.alephium.crypto.ED25519.scala Maven / Gradle / Ivy

There is a newer version: 3.8.8
Show newest version
// Copyright 2018 The Alephium Authors
// This file is part of the alephium project.
//
// The library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the library. If not, see .

package org.alephium.crypto

import scala.util.control.NonFatal

import akka.util.ByteString
import org.bouncycastle.math.ec.rfc8032.{Ed25519 => bcEd25519}

import org.alephium.serde.RandomBytes

class ED25519PrivateKey(val bytes: ByteString) extends PrivateKey {
  def length: Int = ED25519PrivateKey.length

  def publicKey: ED25519PublicKey = {
    val privateBytes = bytes.toArray
    val publicBytes  = Array.ofDim[Byte](bcEd25519.PUBLIC_KEY_SIZE)
    bcEd25519.generatePublicKey(privateBytes, 0, publicBytes, 0)
    ED25519PublicKey.unsafe(ByteString.fromArrayUnsafe(publicBytes))
  }
}

object ED25519PrivateKey
    extends RandomBytes.Companion[ED25519PrivateKey](
      bs => {
        assume(bs.size == bcEd25519.SECRET_KEY_SIZE)
        new ED25519PrivateKey(bs)
      },
      _.bytes
    ) {
  override def length: Int = bcEd25519.SECRET_KEY_SIZE
}

class ED25519PublicKey(val bytes: ByteString) extends PublicKey {
  def length: Int = ED25519PublicKey.length

  def toByte32: Byte32 = Byte32.unsafe(bytes)
}

object ED25519PublicKey
    extends RandomBytes.Companion[ED25519PublicKey](
      bs => {
        assume(bs.size == bcEd25519.PUBLIC_KEY_SIZE)
        new ED25519PublicKey(bs)
      },
      _.bytes
    ) {
  override def length: Int = bcEd25519.PUBLIC_KEY_SIZE
}

class ED25519Signature(val bytes: ByteString) extends Signature {
  def length: Int = ED25519Signature.length
}

object ED25519Signature
    extends RandomBytes.Companion[ED25519Signature](
      bs => {
        assume(bs.size == bcEd25519.SIGNATURE_SIZE)
        new ED25519Signature(bs)
      },
      _.bytes
    ) {
  override def length: Int = bcEd25519.SIGNATURE_SIZE
}

object ED25519 extends SignatureSchema[ED25519PrivateKey, ED25519PublicKey, ED25519Signature] {
  override def generatePriPub(): (ED25519PrivateKey, ED25519PublicKey) = {
    val privateKey = ED25519PrivateKey.generate
    (privateKey, privateKey.publicKey)
  }

  override def secureGeneratePriPub(): (ED25519PrivateKey, ED25519PublicKey) = {
    val privateKey = ED25519PrivateKey.secureGenerate
    (privateKey, privateKey.publicKey)
  }

  protected def sign(message: Array[Byte], privateKey: Array[Byte]): ED25519Signature = {
    val signature = Array.ofDim[Byte](ED25519Signature.length)
    bcEd25519.sign(privateKey, 0, message, 0, message.length, signature, 0)
    ED25519Signature.unsafe(ByteString.fromArrayUnsafe(signature))
  }

  protected def verify(
      message: Array[Byte],
      signature: Array[Byte],
      publicKey: Array[Byte]
  ): Boolean = {
    try {
      bcEd25519.verify(signature, 0, publicKey, 0, message, 0, message.length)
    } catch {
      case NonFatal(_) => false
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy