commit 445fb241229eb9baa1b37f6216d833fc09f1be7a
parent 9c7435c9b0bfc826d26a89ea66396b109d28c2ca
Author: Andrew Laack <andrew@laack.co>
Date: Mon, 1 Jun 2026 22:14:51 -0500
Added flashcards directory
Diffstat:
8 files changed, 348 insertions(+), 2 deletions(-)
diff --git a/docs/UnderstandingMentalModelsInAIDrivenCodeCompletion.md b/docs/UnderstandingMentalModelsInAIDrivenCodeCompletion.md
@@ -25,7 +25,5 @@ The researchers performed an elicitation study with 56 developers to evaluate de
- http://dx.doi.org/10.2139/ssrn.4945566
- http://dx.doi.org/10.48550/ARXIV.2302.06590
- http://dx.doi.org/10.1145/3661145
-- Deskilling
- - http://doi.org/10.1145/3491102.3517578
- [DORA Metrics](DORAMetrics.md)
- [SPACE Framework](SPACEFramework.md)
diff --git a/flashcards/crypto/BlindSignature.md b/flashcards/crypto/BlindSignature.md
@@ -0,0 +1,27 @@
+# Blind Signature
+
+**Source:** [Blind Signatures for Untraceable Payments](https://chaum.com/publications/#z62xPL)
+
+**Definition:** A blind signature is a signature on a message that verifies something about it without leaking information about the content of the message to the signatory.
+
+## Analogy
+
+- Place a completed ballot in a carbon paper lined envelope that has the voter's credentials pre-printed on the outside of the envelope
+- A signatory verifies the credentials and signs the envelope
+ - This would generally amount to making sure the voter's credentials haven't already been used in this election
+ - Since the envelope is carbon lined, the signatory's signature is transferred to the ballot without them knowing the information on the ballot
+- This envelope is given back to the voter
+- The voter opens the envelope and places the signed ballot into an unmarked envelope
+- The voter anonymously sends the unmarked envelope to the election officiants
+- The officiants verify the signatures on each of the ballots and count and put them on display publicly
+ - Only the voter knows what is on their ballot, allowing some information to be placed on the ballot that is only identifiable by them, to verify their ballot was indeed counted, without anyone else knowing which one was theirs
+
+The value of this scheme is that 1) no one can link a vote with a voter 2) trust in signatories from voting officials ensures all votes are valid 3) since only the voter knows what is on their ballot, they can put private information on it, allowing them to validate their vote was counted once they are all displayed publicly.
+
+## Functions
+
+1) Signing function s' known to the signer with a corresponding publicly known inverse s, such that s(s'(x)) = x where s doesn't leak information about s'.
+ - There is a private way to sign a message that is publicly verifiable
+2) Commuting function c and its inverse c', known only to the provider (e.g. voter), such that c'(s'(c(x))=s'(x) and c(x) and s' give no information about x.
+ - I apply a function to my message, send it to the signatory, they sign it, I perform an inversion of the original function I performed on my message such that I am left with a signature on my original message without the signatory knowing what the message is.
+3) Redundancy checking predicate r, that checks for sufficient redundancy to make search for valid signatures impractical
diff --git a/flashcards/crypto/ChaumianECash.md b/flashcards/crypto/ChaumianECash.md
@@ -0,0 +1,27 @@
+# Chaumian eCash
+
+**Source:** [https://en.wikipedia.org/wiki/Ecash/](https://en.wikipedia.org/wiki/Ecash/)
+
+**Definition:** Chaumian eCash (or just eCash),
+
+## Details
+
+Chaumian eCash was introduced in the paper, "Blind Signatures for Untraceable Payments" by David Chaum in 1982.
+
+eCash was introduced as a payment system to provide a degree of privacy for payees while mitigating some negative externalities associated with privacy, like the lack of provable payments. The following are the main properties of this payment system:
+
+1) Inability for third parties to determine payee, time, or amount of payments made by an individual
+2) Ability to provide proof of payment, or to determine the identity of the payee under exceptional conditions
+3) Ability to stop the use of stolen payments
+
+## Limitations
+
+The depository may limit deposits and withdrawls.
+
+## Related Links
+
+- [Blind Signature](BlindSignature.md)
+
+## Relevant Sources
+
+- [Blind Signatures for Untraceable Payments](https://chaum.com/publications/#z62xPL)
diff --git a/flashcards/crypto/Cryptocurrency.md b/flashcards/crypto/Cryptocurrency.md
@@ -0,0 +1,28 @@
+# Cryptocurrency
+
+**Source:** MIT MAS.S62 Cryptocurrency Engineering and Design L1
+
+**Definition:** Cryptocurrency is a digital asset that uses a digital ledger for tracking transactions.
+
+## Some properties we'd like
+
+1. Permissionless
+ - Money can be spent only if it is owned by the individual
+ - No authority limiting transactions
+2. No double spends
+3. Tamper-proof
+ - Can't take back a spend easily
+ - Can't tamper with history
+
+## [Distributed consensus](DistributedConsensus.md)
+
+To achieve distributed consensus it is frequently useful to have a distributed log of transactions. In Bitcoin this is achieved using [Proof of Work](ProofOfWork.md).
+
+## Links
+
+- [Coincidence of Wants](CoincidenceOfWants.md)
+- [Depository](Depository.md)
+- [Chaumian eCash](ChaumianECash.md)
+- [Blockchain](Blockchain.md)
+- [CAP Theorem](CAPTheorem.md)
+- [PACELC](PACELC.md)
diff --git a/flashcards/crypto/DigitalSignature.md b/flashcards/crypto/DigitalSignature.md
@@ -0,0 +1,25 @@
+# Digital Signature
+
+**Source:** Cryptography and Network Security
+
+**Chapter:** 1.6
+
+**Definition:** A digital signature is a value computed with an algorithm and data that outputs a deterministic signature to verify the origin and integrity of the data.
+
+## Functions
+
+There are three necessary functions for digital signatures.
+
+1. publicKey, privateKey := GenerateKeys(randomSeed)
+2. signature := Sign(privateKey, message)
+3. valid := Verify(publicKey, message, signature)
+
+Anyone with the public key can verify a message and signature, only the person with the private key may sign a message.
+
+## Examples
+
+- [Lamport Signature](LamportSignature.md)
+
+## Links
+
+- [Blind Signature](BlindSignature.md)
diff --git a/flashcards/crypto/DistributedConsensus.md b/flashcards/crypto/DistributedConsensus.md
@@ -0,0 +1,17 @@
+# Distributed Consensus
+
+**Source:** MIT MAS.S62 Cryptocurrency Engineering and Design L2
+
+**Definition:** Distributed consensus is the problem of trying to get multiple systems to agree on a value in the presence of faults.
+
+## Crash fault tolerance (CFT)
+
+CFT algorithms can achieve consensus despite the failure of some network nodes. Despite this, they are not resilient to adversarial nodes on the network, an issue that must be addressed for [Cryptocurrency](Cryptocurrency.md).
+
+## Byzantine fault tolerance (BFT)
+
+Byzantine fault tolerant algorithms can achieve consensus even if some network nodes are malicious or malfunctioning.
+
+Historically, these algorithms have been identity-based, requiring the identity of every node to be known. This could allow adversaries to create many identities, known as a [Sybil attack](SybilAttack.md).
+
+A possible solution to this problem is to make identity creation cost a scarce resource.
diff --git a/flashcards/crypto/HashFunction.md b/flashcards/crypto/HashFunction.md
@@ -0,0 +1,53 @@
+# Hash Function
+
+Ch. 5
+
+**Definition:** A hash function is a function f(k) that takes a key value k (x.r = k where x is an object) and outputs a natural number.
+
+f : K -> N where K is the set of all possible keys and N is the natural numbers.
+
+Oftentimes we also want to state that the set of valid outputs (image of f) is from 0 to m-1 where m is the length of the array we are using to store the objects of the given hash value.
+
+### n-bit hash functions
+
+**Definition:** n-bit hash functions are hash functions such that their image is the natural numbers from 0 to 2^n-1.
+
+These hash function can then map to all permuations of bits with a length of n.
+
+### Important aspects of the hashing function
+
+1. Speed
+2. One-way
+3. Deterministic
+4. Uniform
+
+Speed - this means the time to compute the hash for the inputs is generally fast
+
+One-way - this means it is hard to go the opposite direction namely from N -> K
+
+Deterministic - this means for the same input the output should always be the same
+
+Uniform - the distribution, with respect to K, should be roughly uniform across the image of the function - [0, m-1]
+
+### Perfect
+
+A hash function is perfect if for all valid inputs, there are no collisions (one-to-one).
+
+$f:K \to N$ is a perfect hash function if
+$\forall x,y\in K, f(x) \neq f(y) \text{ where } y \neq x$
+
+## Cryptographic hash functions
+
+The above is discussing hash functions, primarily in the context of [hashtables](HashTable.md), but expectations differ when using hash functions for cryptography.
+
+### Requirements for a good cryptographic hash function
+
+1. Deterministic
+2. Any size input results in a fixed size output
+3. Preimage resistance
+ - Given y such that hash(x) = y it shouldn't be reasonable to find x.
+4. 2nd preimage resistance
+ - Given x,y such that hash(x) = y it shouldn't be reasonable to find x' such that hash(x') = y.
+5. Collision resistance
+ - It isn't reasonable to find x != z such that hash(x) = hash(z)
+ - This was the broken expectation that led to sha-1 and md5 being considered insecure
diff --git a/flashcards/crypto/LamportSignature.md b/flashcards/crypto/LamportSignature.md
@@ -0,0 +1,171 @@
+# Lamport Signature
+
+**Source:** MIT MAS.S62 Cryptocurrency Engineering and Design L1
+
+**Definition:** The Lamport signature scheme is a single use signature scheme where portions of a private key are leaked to prove the private key is known by the sender of the message, as a way to sign the message.
+
+## Specifics
+
+### Key Generation
+
+To generate a private key you generate a pair of 256 256 bit segments of random data. Since 256 bits is 32 bytes, we see the total size of the private key is 16kb (16384 bytes)
+
+To generate the public key we perform hashing on the data from the private key. Specifically, since the sha256 hash function gives hashes that are exactly 256 bits, we apply the hash function to each of the 512 segments of 256 bits above to generate a public key where each of the resulting segments is the hash of the associated segment from the private key. It is still worthwhile to consider the public key as two keys each with 256 segments, but for the purposes of public key generation this doesn't matter.
+
+### Signing Messages
+
+To sign a message we first hash the message using the sha256 hash function. This gives us 256 bits of data to work with.
+
+Using these 256 bits of data, we perform the operations specified in the below pseudocode:
+
+```
+
+signature = ""
+for idx in range(hash)
+ if hash[idx] == 0:
+ signature += privateKey.first[idx]
+ if hash[idx] == 1:
+ signature += privateKey.second[idx]
+return signature
+
+```
+
+The signature is thus exactly half of the private key where the half revealed is (generally) some portion of the first half and some portion second half of the private key, based on value of the current bit from the message hash.
+
+### Verifying Messages
+
+To verify a message we iterate over each of the bits from the message's hash and verify the segments revealed as the private key hash to the associated segments of the public key.
+
+```
+for idx in range(hash):
+ if hash[idx] == 0:
+ assert sha256sum(privateKey.first[idx]) == publicKey[idx]
+ if hash[idx] == 1:
+ assert sha256sum(privateKey.second[idx]) == publicKey[idx]
+```
+
+## Limitations
+
+- The keys for lamport signatures, along with the signatures themselves, are large
+ - public / private keys are 16kb
+ - signatures are 8kb
+- Keys should only be used once
+ - One iteration leaks half of the key
+ - Two iterations leaks ~3/4 of the key
+ - Depending on the message being signed, even more segments may be revealed
+ - ...
+
+## Benefits
+
+- Simple to implement
+- Cheap to compute
+ - No large primes
+- Quantum resistant
+ - Impacted by grover's algorithm so expect 128 bits of security instead of 256 when facing quantum computers
+ - This is generally considered acceptable
+
+## Implementation
+
+```go
+
+package main
+
+import (
+ "crypto/rand"
+ "crypto/sha256"
+ "fmt"
+)
+
+type Key struct {
+ firstRow [256][32]byte
+ secondRow [256][32]byte
+}
+
+func GenerateKeys() (Key, Key) {
+
+ privateKey := Key{}
+
+ for i := range 256 {
+ _, err := rand.Read(privateKey.firstRow[i][:])
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ for i := range 256 {
+ _, err := rand.Read(privateKey.secondRow[i][:])
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ publicKey := Key{}
+
+ for i := range 256 {
+ publicKey.firstRow[i] = sha256.Sum256(privateKey.firstRow[i][:])
+ }
+
+ for i := range 256 {
+ publicKey.secondRow[i] = sha256.Sum256(privateKey.secondRow[i][:])
+
+ }
+
+ return publicKey, privateKey
+}
+
+func Sign(privateKey Key, message string) [256][32]byte {
+
+ messageHash := sha256.Sum256([]byte(message))
+
+ signature := [256][32]byte{}
+
+ for index := range 32 {
+ currentByteString := fmt.Sprintf("%08b", messageHash[index])
+ for idx := range 8 {
+ currentBit := currentByteString[idx]
+ if currentBit == '0' {
+ signature[(index*8)+idx] = privateKey.firstRow[(index*8)+idx]
+ } else {
+ signature[(index*8)+idx] = privateKey.secondRow[(index*8)+idx]
+ }
+ }
+ }
+
+ return signature
+}
+
+func Verify(publicKey Key, message string, signature [256][32]byte) bool {
+
+ messageHash := sha256.Sum256([]byte(message))
+
+ for index := range 32 {
+ currentByteString := fmt.Sprintf("%08b", messageHash[index])
+ for idx := range 8 {
+ currentBit := currentByteString[idx]
+ if currentBit == '0' {
+ // signature[(index * 8) + idx] = privateKey.firstRow[(index * 8) + idx]
+ if sha256.Sum256(signature[(index*8)+idx][:]) != publicKey.firstRow[(index*8)+idx] {
+ return false
+ }
+ } else {
+ if sha256.Sum256(signature[(index*8)+idx][:]) != publicKey.secondRow[(index*8)+idx] {
+ return false
+ }
+ }
+ }
+ }
+
+ return true
+
+}
+
+func main() {
+
+ publicKey, privateKey := GenerateKeys()
+ message := rand.Text()
+ signature := Sign(privateKey, message)
+ valid := Verify(publicKey, message, signature)
+ fmt.Printf("Verified message matches signature: %v\n", valid)
+
+}
+```