Bernstein Open Verification Protocol - Version 1.0
What do you need
- A copy of the certificate
- A copy of all of the project files, including the project cover page
- Optionally, to prove ownership, the private keys used to generate the certificate
Download the certificate
Download the project files
Download the private keys
Proving existence and integrity
- Compute the SHA256 hash of the files. There are a lot of software utilities that you may use. As an example, on Linux systems, you can compute the SHA256 has of any fily by running the following command:
sha256sum -b <filename>
- Now we compute and store the hash of every file. * For the cover, we compute two rounds of SHA256. SHA256(SHA256(coverFile)) * When we have all thoses hashes, we sort them by alphabetical order and concatenate them together. * Finally we compute the hash of this string, and if every file is exactly the same as the ones certified, the final hash will match the project hash displayed on your certificate. * The project hash is a standard ECDSA private key. The public key will be the same as the data public key on your certificate.
This data key pair is the proof that the files certified are stored on the Bitcoin blockchain. The bitcoin address is generated with the 3 public keys on the certificate, which includes the data public key which is generated in a unique way from your files. The address is generated like this :
redeemScript = <OP_3> <Owner pubkey> <Data pubkey> <Bernstein pubkey> <OP_3> <OP_CHECKMULTISIG>
redeemScriptHash = RIPEMD160(SHA256(redeemScript))
address = Base58Check.Encode(redeemScriptHash)
RIPEMD160 is another hashing algorithm used by the bitcoin standard.
The Base58Check encoding is the encoding used by the bitcoin standard for addresses.
Certificate Ownership (for bitcoin certificates)
Since the Bitcoin blockchain is public digital infrastructure, you can easily look up the transaction referenced on your certificate. Copy the transaction identifier (TX) from the certificate and enter it in any Bitcoin blockchain explorer service (BlockCypher, TradeBlock, BitcoinChain, ...). You can also decode the raw transaction with this tool.
To prove the ownership of the certificate, we need to prove that we own the output of the bitcoin transaction broadcasted at the certificate creation.
We can identifiy the transaction on the blockchain with the transaction ID present on the certificate. This transaction is a P2SH (pay-to-script-hash) 3-of-3 Multisig transaction which is created with the 3 public keys present on your certificate. P2SH transactions can add spending conditions to the output of the transaction. A 3-of-3 Multisig transaction means that we need the 3 private keys associated with the 3 public keys to spend the output.
These spending conditions are known as the redeem script, and a P2SH funding transaction simply contains a hash of this redeem script in the scriptPubKey of the funding transaction. The redeem script itself is only revealed, checked against the redeem script hash, and evaluated during the spending transaction.
To prove that we own the output of this transaction, we need to prove that we can spend it. For this we will need the 3 private keys associated with the public keys from your certificate : the Owner private key, the Data private key and the Bernstein private key. We can get the private keys from the Bernstein main application.
Owner private Key
What: a private key derived from the organization master private key with a deterministic derivation_path (BIP32) Who: only in possession of the organization owner, never disclosed to Bernstein server.
Data Private Key
What: a private/public key pair derived deterministically from the collection of files included in the project when the certificate was generated. Who: anyone having access to those files can calculate the key.
Bernstein Private Key
What: an organization specific key pair randomly generated by Bernstein to secure the integrity and consistency of the chain of certificates. Who: the key is only disclosed to the organization owner.
With the 3 private keys we can prove that we own the certificate. In the verifiy app we create a fake transaction ( a transaction which we will not broadcast to the bitcoin network) which would spend the output of the certificate transaction. We create this transaction using the scriptPubKey (hash of the redeem script) extracted from the raw P2SH funding transaction, but we could generate it again with the public keys from the certificate. The redeem script looks like this (decoded):
<OP_3> <Owner pubkey> <Data pubkey> <Bernstein pubkey> <OP_3> <OP_CHECKMULTISIG>
To provide the scriptPubKey, we need to hash the redeem script :
redeemScriptHash = RIPEMD160(SHA256(redeemScript))
You can get the hash of the redeem script from the funding transaction, or you can get the redeem script yourself from this website, providing the public keys in the right order (Owner public key, Data public key, Bernstein public key). You can decode it here.
Then we need to sign this fake transaction with the 3 private keys to use it in the signature script which will verify that we can spend the output.
We finally run this script with a bitcoin script interpreter which will return a boolean (true or false) indicating if the private keys signature match with the public keys used to create the certificate transaction. The script will look like this :
<OP_0> <sig OwnerPrivateKey> <sig DataPrivateKey> <sig BernsteinPrivateKey> <redeemScript> <OP_HASH160> <scriptPubkey> <OP_EQUAL>
To prove to other people that we own those specific private keys, we could sign a message with each of the private keys and thoses signatures could be verified by third parties with the three public keys.