Last active
June 21, 2022 14:45
-
-
Save jorpic/75079a1c5fd5f5ac069626c10abb39b5 to your computer and use it in GitHub Desktop.
Pedersen commitment in ed25519-java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package kz.cbdc.crypto.commitment | |
import java.util.Random | |
import java.math.BigInteger | |
import org.junit.jupiter.api.Assertions.* | |
import org.junit.jupiter.api.Test | |
import net.i2p.crypto.eddsa.Utils | |
import net.i2p.crypto.eddsa.math.FieldElement | |
import net.i2p.crypto.eddsa.math.bigint.BigIntegerLittleEndianEncoding | |
import net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding | |
import kz.cbdc.crypto.prelude.* | |
val enc = BigIntegerLittleEndianEncoding().also { | |
it.setField(ed25519.curve.field) | |
} | |
val dec = Ed25519LittleEndianEncoding().also { | |
it.setField(ed25519.curve.field) | |
} | |
fun BigInteger.toFieldElement(): FieldElement = dec.decode(enc.encode(this)) | |
fun FieldElement.toHex(): String = Utils.bytesToHex(this.toByteArray()) | |
class CommitmentTest { | |
@Test | |
fun testMultiplicationDistributivity() { | |
val rnd = Random() | |
val a1 = BigInteger(42, rnd) | |
val a2 = BigInteger(42, rnd) | |
val a0 = a1 + a2 | |
assertEquals(a1 + a2, a0) | |
val b0 = a0.toFieldElement() | |
val b1 = a1.toFieldElement() | |
val b2 = a2.toFieldElement() | |
assertEquals( | |
b1.add(b2).toHex(), | |
b0.toHex() | |
) | |
val g = G.doubleScalarMultiplyVariableTime( | |
G, | |
b1.toByteArray(), | |
b2.toByteArray()) | |
val h = G mul (b1.add(b2).toByteArray()) | |
assertEquals(g.toHex(), h.toHex()) | |
} | |
@Test | |
fun testCommitmentHomomorphism() { | |
val k0 = randomKey() | |
val k1 = randomKey() | |
val k2 = randomKey() | |
val rnd = Random() | |
val a1 = BigInteger(42, rnd).toFieldElement() | |
val a2 = BigInteger(42, rnd).toFieldElement() | |
val a0 = a1.add(a2) | |
val f = G.doubleScalarMultiplyVariableTime( | |
H, | |
a0.toByteArray(), | |
k0) | |
.precompute() | |
val g = G.doubleScalarMultiplyVariableTime( | |
H, | |
a1.toByteArray(), | |
k1) | |
.precompute() | |
val h = G.doubleScalarMultiplyVariableTime( | |
H, | |
a2.toByteArray(), | |
k2) | |
.precompute() | |
val sumOfCommitments = f.negate() | |
.add(g.toCached()).precompute() | |
.add(h.toCached()) | |
val keyExcess = | |
(G mul k0).precompute().negate() | |
.add((G mul k1).toCached()).precompute() | |
.add((G mul k2).toCached()) | |
assertEquals( | |
sumOfCommitments.toHex(), | |
keyExcess.toHex() | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment