User Tools

Site Tools


Blockchain simple sample

With rsa/sha sign of node/section

NEED

  • verify chain
x6.go
/*
 * Copyright 2020 Oleg Borodin  <borodin@unix7.org>
 */
 
package main
 
import (
    "fmt"
    "encoding/pem"
    "crypto"
    "crypto/rsa"
    "crypto/rand"
    "crypto/sha256"
    "encoding/asn1"
)
 
type Payload struct {
    Number      int64
    PublicKey   rsa.PublicKey
    Blob        []byte
    PrevHash    []byte
}
 
type Section struct {
    PayloadAsn1 []byte
    Hash        []byte
    Signature   []byte
}
 
func generateKey() (*rsa.PrivateKey, *rsa.PublicKey) {
 
    var err error
    var privateKey *rsa.PrivateKey
    var publicKey *rsa.PublicKey
 
    privateKey, err = rsa.GenerateKey(rand.Reader, 1024)
    if err != nil {
        panic(err)
    }
    publicKey = &privateKey.PublicKey
    return privateKey, publicKey
}
 
func createSection(number int64, privateKey *rsa.PrivateKey, publicKey *rsa.PublicKey, blob []byte, prevHash []byte) Section {
 
    var err error
    payload := Payload{
        Number:     number,
        PublicKey:  *publicKey,
        Blob:       blob,
        PrevHash:   prevHash,
    }
 
    payloadAsn1, err := asn1.Marshal(payload)
    if err != nil {
        panic(err)
    }
 
    hash := sha256.Sum256(payloadAsn1)
 
    signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
    if err != nil {
        panic(err)
    }
 
    return Section{
        PayloadAsn1:    payloadAsn1,
        Hash:           hash[:],
        Signature:      signature,
    }
}
 
func verifySectionSign(section Section) error {
    var err error
    var payload Payload
 
    _, err = asn1.Unmarshal(section.PayloadAsn1, &payload)
    if err != nil {
        panic(err)
    }
 
    hash := sha256.Sum256(section.PayloadAsn1)
 
    err = rsa.VerifyPKCS1v15(&payload.PublicKey, crypto.SHA256, hash[:], section.Signature)
    return err
}
 
func main() {
 
    privateKey, publicKey := generateKey()
 
    blob := []byte("payload message")
    var prevHash []byte
 
    section := createSection(1, privateKey, publicKey, blob, prevHash)
 
    sectionAsn1, err := asn1.Marshal(section)
    if err != nil {
        panic(err)
    }
 
    sectionBlock := &pem.Block{
        Type: "SECTION",
        Bytes: sectionAsn1,
    }
    sectionPem := pem.EncodeToMemory(sectionBlock)
    fmt.Println(string(sectionPem))
 
    if verifySectionSign(section) == nil {
        fmt.Println("section signature is fine")
    }
}

output

$ go run x6.go

-----BEGIN SECTION-----
MIIBTQSBpTCBogIBATCBiQKBgQC4eeGn0cQ55EGgDOm57MAJkItBxtnghGMnOexv
8VPoBl1eFabm/sgSXu52kCp1iXVBhJnWPYb8YuIZ3mUCSVQMUlN5vnss/aj/Lfkq
cg360k0nPWKKVsVQmosEIz12AJYYqvId2Vrh7ZOBWZTbecu3V4oQ55fuunEaTBak
65XizwIDAQABBA9wYXlsb2FkIG1lc3NhZ2UEAAQg5Ym3ww7ve86N6XI9CCTWfjBz
223iQ4SS3d82OYh3NYcEgYAKIABNcc+PNMYAxiTLuBQuekmuJ5nWXoktmy1XdQrW
EYYDXsjD0jANKqV9jJyP5TeON1TLo6bfyiVvuD/MSbO/y57ypC4X9vTi/Y3ITdOq
8X26AA/xCMYTnyyEbbTGh9bDX0Q7aavdAZZJEV+F5cOTPSGJvLlTYVFfvCPGOHUv
GQ==
-----END SECTION-----

section signature is fine