mirror of
https://github.com/logos-storage/logos-storage-nim-validator.git
synced 2026-01-07 16:03:11 +00:00
transaction signing
This commit is contained in:
parent
ac4413fce5
commit
56ec9a03c2
@ -1,28 +0,0 @@
|
|||||||
import pkg/protobuf_serialization
|
|
||||||
|
|
||||||
export protobuf_serialization
|
|
||||||
|
|
||||||
type
|
|
||||||
TransactionMessage* {.proto3.} = object
|
|
||||||
version* {.fieldNumber: 1, pint.}: uint32
|
|
||||||
kind* {.fieldNumber: 2, pint.}: uint32
|
|
||||||
requestId* {.fieldNumber: 3.}: seq[byte]
|
|
||||||
slotIndex* {.fieldNumber: 4, pint.}: uint32
|
|
||||||
period* {.fieldNumber: 5, pint.}: uint64
|
|
||||||
merkleRoot* {.fieldNumber: 6.}: seq[byte]
|
|
||||||
challenge* {.fieldNumber: 7.}: seq[byte]
|
|
||||||
proof* {.fieldNumber: 8.}: Groth16ProofMessage
|
|
||||||
Groth16ProofMessage* {.proto3.} = object
|
|
||||||
a* {.fieldNumber: 1.}: G1PointMessage
|
|
||||||
b* {.fieldNumber: 2.}: G2PointMessage
|
|
||||||
c* {.fieldNumber: 3.}: G1PointMessage
|
|
||||||
G1PointMessage* {.proto3.} = object
|
|
||||||
x* {.fieldNumber: 1.}: seq[byte]
|
|
||||||
y* {.fieldNumber: 2.}: seq[byte]
|
|
||||||
G2PointMessage* {.proto3.} = object
|
|
||||||
x* {.fieldNumber: 1.}: Fp2ElementMessage
|
|
||||||
y* {.fieldNumber: 2.}: Fp2ElementMessage
|
|
||||||
Fp2ElementMessage* {.proto3.} = object
|
|
||||||
real* {.fieldNumber: 1.}: seq[byte]
|
|
||||||
imag* {.fieldNumber: 2.}: seq[byte]
|
|
||||||
|
|
||||||
@ -1,86 +1,7 @@
|
|||||||
import ./basics
|
import ./transaction/transaction
|
||||||
import ./transaction/storagerequest
|
import ./transaction/signed
|
||||||
import ./transaction/period
|
import ./transaction/serialization
|
||||||
import ./transaction/groth16
|
|
||||||
|
|
||||||
export storagerequest
|
export transaction
|
||||||
export period
|
export signed
|
||||||
export groth16
|
export serialization.toBytes
|
||||||
|
|
||||||
type
|
|
||||||
TransactionVersion* {.pure.} = enum
|
|
||||||
version0
|
|
||||||
TransactionKind* {.pure.} = enum
|
|
||||||
storageProof
|
|
||||||
missingProof
|
|
||||||
Transaction* = object
|
|
||||||
requestId: StorageRequestId
|
|
||||||
slotIndex: uint32
|
|
||||||
period: Period
|
|
||||||
merkleRoot: UInt256
|
|
||||||
challenge: UInt256
|
|
||||||
case kind: TransactionKind
|
|
||||||
of storageProof:
|
|
||||||
proof: Groth16Proof
|
|
||||||
of missingProof:
|
|
||||||
discard
|
|
||||||
|
|
||||||
func storageProof*(
|
|
||||||
_: type Transaction,
|
|
||||||
requestId: StorageRequestId,
|
|
||||||
slotIndex: uint32,
|
|
||||||
period: Period,
|
|
||||||
merkleRoot: UInt256,
|
|
||||||
challenge: UInt256,
|
|
||||||
proof: Groth16Proof
|
|
||||||
): Transaction =
|
|
||||||
Transaction(
|
|
||||||
kind: TransactionKind.storageProof,
|
|
||||||
requestId: requestId,
|
|
||||||
period: period,
|
|
||||||
slotIndex: slotIndex,
|
|
||||||
merkleRoot: merkleRoot,
|
|
||||||
challenge: challenge,
|
|
||||||
proof: proof
|
|
||||||
)
|
|
||||||
|
|
||||||
func missingProof*(
|
|
||||||
_: type Transaction,
|
|
||||||
requestId: StorageRequestId,
|
|
||||||
slotIndex: uint32,
|
|
||||||
period: Period,
|
|
||||||
merkleRoot: UInt256,
|
|
||||||
challenge: UInt256,
|
|
||||||
): Transaction =
|
|
||||||
Transaction(
|
|
||||||
kind: TransactionKind.missingProof,
|
|
||||||
requestId: requestId,
|
|
||||||
slotIndex: slotIndex,
|
|
||||||
period: period,
|
|
||||||
merkleRoot: merkleRoot,
|
|
||||||
challenge: challenge
|
|
||||||
)
|
|
||||||
|
|
||||||
func version*(transaction: Transaction): TransactionVersion =
|
|
||||||
TransactionVersion.version0
|
|
||||||
|
|
||||||
func kind*(transaction: Transaction): TransactionKind =
|
|
||||||
transaction.kind
|
|
||||||
|
|
||||||
func requestId*(transaction: Transaction): StorageRequestId =
|
|
||||||
transaction.requestId
|
|
||||||
|
|
||||||
func slotIndex*(transaction: Transaction): uint32 =
|
|
||||||
transaction.slotIndex
|
|
||||||
|
|
||||||
func period*(transaction: Transaction): Period =
|
|
||||||
transaction.period
|
|
||||||
|
|
||||||
func merkleRoot*(transaction: Transaction): UInt256 =
|
|
||||||
transaction.merkleRoot
|
|
||||||
|
|
||||||
func challenge*(transaction: Transaction): UInt256 =
|
|
||||||
transaction.challenge
|
|
||||||
|
|
||||||
func proof*(transaction: Transaction): Groth16Proof =
|
|
||||||
transaction.proof
|
|
||||||
|
|||||||
@ -1,6 +1,33 @@
|
|||||||
import ./basics
|
import pkg/protobuf_serialization
|
||||||
|
import ../basics
|
||||||
import ./transaction
|
import ./transaction
|
||||||
import ./serialization/protobuf
|
|
||||||
|
export protobuf_serialization
|
||||||
|
|
||||||
|
type
|
||||||
|
TransactionMessage* {.proto3.} = object
|
||||||
|
version* {.fieldNumber: 1, pint.}: uint32
|
||||||
|
kind* {.fieldNumber: 2, pint.}: uint32
|
||||||
|
requestId* {.fieldNumber: 3.}: seq[byte]
|
||||||
|
slotIndex* {.fieldNumber: 4, pint.}: uint32
|
||||||
|
period* {.fieldNumber: 5, pint.}: uint64
|
||||||
|
merkleRoot* {.fieldNumber: 6.}: seq[byte]
|
||||||
|
challenge* {.fieldNumber: 7.}: seq[byte]
|
||||||
|
proof* {.fieldNumber: 8.}: Groth16ProofMessage
|
||||||
|
Groth16ProofMessage* {.proto3.} = object
|
||||||
|
a* {.fieldNumber: 1.}: G1PointMessage
|
||||||
|
b* {.fieldNumber: 2.}: G2PointMessage
|
||||||
|
c* {.fieldNumber: 3.}: G1PointMessage
|
||||||
|
G1PointMessage* {.proto3.} = object
|
||||||
|
x* {.fieldNumber: 1.}: seq[byte]
|
||||||
|
y* {.fieldNumber: 2.}: seq[byte]
|
||||||
|
G2PointMessage* {.proto3.} = object
|
||||||
|
x* {.fieldNumber: 1.}: Fp2ElementMessage
|
||||||
|
y* {.fieldNumber: 2.}: Fp2ElementMessage
|
||||||
|
Fp2ElementMessage* {.proto3.} = object
|
||||||
|
real* {.fieldNumber: 1.}: seq[byte]
|
||||||
|
imag* {.fieldNumber: 2.}: seq[byte]
|
||||||
|
|
||||||
|
|
||||||
func toBytes*(transaction: Transaction): seq[byte] =
|
func toBytes*(transaction: Transaction): seq[byte] =
|
||||||
var message = TransactionMessage(
|
var message = TransactionMessage(
|
||||||
36
codexvalidator/transaction/signed.nim
Normal file
36
codexvalidator/transaction/signed.nim
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import ../signatures
|
||||||
|
import ./transaction
|
||||||
|
import ./serialization
|
||||||
|
|
||||||
|
type SignedTransaction* = object
|
||||||
|
transaction: Transaction
|
||||||
|
signer: Identifier
|
||||||
|
signature: Signature
|
||||||
|
|
||||||
|
func init*(
|
||||||
|
_: type SignedTransaction,
|
||||||
|
transaction: Transaction,
|
||||||
|
signer: Identifier,
|
||||||
|
signature: Signature
|
||||||
|
): SignedTransaction =
|
||||||
|
SignedTransaction(
|
||||||
|
transaction: transaction,
|
||||||
|
signer: signer,
|
||||||
|
signature: signature
|
||||||
|
)
|
||||||
|
|
||||||
|
func sign*(identity: Identity, transaction: Transaction): SignedTransaction =
|
||||||
|
let signature = identity.sign(transaction.toBytes())
|
||||||
|
SignedTransaction.init(transaction, identity.identifier, signature)
|
||||||
|
|
||||||
|
func transaction*(signed: SignedTransaction): Transaction =
|
||||||
|
signed.transaction
|
||||||
|
|
||||||
|
func signer*(signed: SignedTransaction): Identifier =
|
||||||
|
signed.signer
|
||||||
|
|
||||||
|
func signature*(signed: SignedTransaction): Signature =
|
||||||
|
signed.signature
|
||||||
|
|
||||||
|
func verifySignature*(signed: SignedTransaction): bool =
|
||||||
|
signed.signer.verify(signed.transaction.toBytes(), signed.signature)
|
||||||
105
codexvalidator/transaction/transaction.nim
Normal file
105
codexvalidator/transaction/transaction.nim
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import ../basics
|
||||||
|
import ./storagerequest
|
||||||
|
import ./period
|
||||||
|
import ./groth16
|
||||||
|
|
||||||
|
export storagerequest
|
||||||
|
export period
|
||||||
|
export groth16
|
||||||
|
|
||||||
|
type
|
||||||
|
TransactionVersion* {.pure.} = enum
|
||||||
|
version0
|
||||||
|
TransactionKind* {.pure.} = enum
|
||||||
|
storageProof
|
||||||
|
missingProof
|
||||||
|
Transaction* = object
|
||||||
|
requestId: StorageRequestId
|
||||||
|
slotIndex: uint32
|
||||||
|
period: Period
|
||||||
|
merkleRoot: UInt256
|
||||||
|
challenge: UInt256
|
||||||
|
case kind: TransactionKind
|
||||||
|
of storageProof:
|
||||||
|
proof: Groth16Proof
|
||||||
|
of missingProof:
|
||||||
|
discard
|
||||||
|
|
||||||
|
func storageProof*(
|
||||||
|
_: type Transaction,
|
||||||
|
requestId: StorageRequestId,
|
||||||
|
slotIndex: uint32,
|
||||||
|
period: Period,
|
||||||
|
merkleRoot: UInt256,
|
||||||
|
challenge: UInt256,
|
||||||
|
proof: Groth16Proof
|
||||||
|
): Transaction =
|
||||||
|
Transaction(
|
||||||
|
kind: TransactionKind.storageProof,
|
||||||
|
requestId: requestId,
|
||||||
|
period: period,
|
||||||
|
slotIndex: slotIndex,
|
||||||
|
merkleRoot: merkleRoot,
|
||||||
|
challenge: challenge,
|
||||||
|
proof: proof
|
||||||
|
)
|
||||||
|
|
||||||
|
func missingProof*(
|
||||||
|
_: type Transaction,
|
||||||
|
requestId: StorageRequestId,
|
||||||
|
slotIndex: uint32,
|
||||||
|
period: Period,
|
||||||
|
merkleRoot: UInt256,
|
||||||
|
challenge: UInt256,
|
||||||
|
): Transaction =
|
||||||
|
Transaction(
|
||||||
|
kind: TransactionKind.missingProof,
|
||||||
|
requestId: requestId,
|
||||||
|
slotIndex: slotIndex,
|
||||||
|
period: period,
|
||||||
|
merkleRoot: merkleRoot,
|
||||||
|
challenge: challenge
|
||||||
|
)
|
||||||
|
|
||||||
|
func version*(transaction: Transaction): TransactionVersion =
|
||||||
|
TransactionVersion.version0
|
||||||
|
|
||||||
|
func kind*(transaction: Transaction): TransactionKind =
|
||||||
|
transaction.kind
|
||||||
|
|
||||||
|
func requestId*(transaction: Transaction): StorageRequestId =
|
||||||
|
transaction.requestId
|
||||||
|
|
||||||
|
func slotIndex*(transaction: Transaction): uint32 =
|
||||||
|
transaction.slotIndex
|
||||||
|
|
||||||
|
func period*(transaction: Transaction): Period =
|
||||||
|
transaction.period
|
||||||
|
|
||||||
|
func merkleRoot*(transaction: Transaction): UInt256 =
|
||||||
|
transaction.merkleRoot
|
||||||
|
|
||||||
|
func challenge*(transaction: Transaction): UInt256 =
|
||||||
|
transaction.challenge
|
||||||
|
|
||||||
|
func proof*(transaction: Transaction): Groth16Proof =
|
||||||
|
transaction.proof
|
||||||
|
|
||||||
|
func `==`*(a, b: Transaction): bool =
|
||||||
|
if a.kind != b.kind:
|
||||||
|
return false
|
||||||
|
if a.requestId != b.requestId:
|
||||||
|
return false
|
||||||
|
if a.slotIndex != b.slotIndex:
|
||||||
|
return false
|
||||||
|
if a.period != b.period:
|
||||||
|
return false
|
||||||
|
if a.merkleRoot != b.merkleRoot:
|
||||||
|
return false
|
||||||
|
if a.challenge != b.challenge:
|
||||||
|
return false
|
||||||
|
case a.kind
|
||||||
|
of TransactionKind.storageProof:
|
||||||
|
a.proof == b.proof
|
||||||
|
of TransactionKind.missingProof:
|
||||||
|
true
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import std/random
|
import std/random
|
||||||
import codexvalidator/basics
|
import codexvalidator/basics
|
||||||
import codexvalidator/transaction
|
import codexvalidator/transaction
|
||||||
|
import codexvalidator/signatures
|
||||||
|
|
||||||
proc example*[T: SomeInteger](_: type T): T =
|
proc example*[T: SomeInteger](_: type T): T =
|
||||||
rand(T)
|
rand(T)
|
||||||
@ -67,3 +68,6 @@ proc example*(_: type Transaction): Transaction =
|
|||||||
challenge,
|
challenge,
|
||||||
proof
|
proof
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc example*(_: type Identity): Identity =
|
||||||
|
Identity.random(result)
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import std/unittest
|
import std/unittest
|
||||||
import codexvalidator/basics
|
import codexvalidator/basics
|
||||||
import codexvalidator/transaction
|
import codexvalidator/transaction
|
||||||
import codexvalidator/serialization
|
import codexvalidator/transaction/serialization
|
||||||
import codexvalidator/serialization/protobuf
|
|
||||||
import ./examples
|
import ./examples
|
||||||
|
|
||||||
suite "Serialization":
|
suite "Transaction serialization":
|
||||||
|
|
||||||
test "serializes a transaction with protobuf":
|
test "serializes a transaction with protobuf":
|
||||||
let transaction = Transaction.example
|
let transaction = Transaction.example
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import std/unittest
|
import std/unittest
|
||||||
import codexvalidator/basics
|
import codexvalidator/basics
|
||||||
|
import codexvalidator/signatures
|
||||||
import codexvalidator/transaction
|
import codexvalidator/transaction
|
||||||
import ./examples
|
import ./examples
|
||||||
|
|
||||||
@ -40,3 +41,20 @@ suite "Transaction":
|
|||||||
test "transactions have a fixed version":
|
test "transactions have a fixed version":
|
||||||
let transaction = Transaction.example
|
let transaction = Transaction.example
|
||||||
check transaction.version == TransactionVersion.version0
|
check transaction.version == TransactionVersion.version0
|
||||||
|
|
||||||
|
test "transactions can be signed":
|
||||||
|
let identity = Identity.example
|
||||||
|
let transaction = Transaction.example
|
||||||
|
let signed = identity.sign(transaction)
|
||||||
|
check signed.transaction == transaction
|
||||||
|
check signed.signer == identity.identifier
|
||||||
|
check signed.signature == identity.sign(transaction.toBytes())
|
||||||
|
|
||||||
|
test "transaction signature can be verified":
|
||||||
|
let identity = Identity.example
|
||||||
|
let transaction = Transaction.example
|
||||||
|
let signed = identity.sign(transaction)
|
||||||
|
check signed.verifySignature()
|
||||||
|
let forger = Identity.example.identifier
|
||||||
|
let forged = SignedTransaction.init(transaction, forger, signed.signature)
|
||||||
|
check not forged.verifySignature()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user