// SHA Painting - with Text Input // And music output - Digest the Digest // Cryptocurrency Blues - John Clavin Sept 30, 2019 // San Bernardino, California function preload() { soundFormats('wav'); wingTip = loadSound('wteint.wav'); } var sha256_1; var sha256_2; var sha256_3; var shaInts_1 = []; var shaInts_2 = []; var shaInts_3 = []; var input; var button; var musicButton; var square1 = []; var square2 = []; var square3 = []; var square4 = []; var square5 = []; var hotSpot = []; var squaresArray = []; var arraysSorted = []; var numbersA = []; var numbersB = []; var numbersC = []; var numbersD = []; var numbersE = []; var numbersF = []; var notesA2play = []; var notesB2play = []; var notesC2play = []; var numCroNotes; var numScaleNotes; var goMusic; var waitMusic; var timeCount; var noteCount; var arrangeCount; var noteArray = [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]; function setup() { // var shapCanvas = createCanvas(768, 768); // shapCanvas.parent('shapContainer'); createCanvas(768, 768); background(230); frameRate(60); goMusic = false; waitMusic = true; timeCount = 0; noteCount = 0; arrangeCount = 0; numCroNotes = 16; jcOsc(); masterVolume(0.50); wingTip.playMode('restart'); wingTip.setVolume(1.0); reverbWt = new p5.Reverb(); reverbWt.process(wingTip, 1.50, 1.6); reverbWt.amp(2.6); rectMode(CENTER); noStroke(); textSize(13); createDiv(); input = createInput(); button = createButton('submit'); button.mousePressed(hashTruth); musicButton = createButton('Play Jazz'); musicButton.mousePressed(startMusic); } function hashTruth() { background(230); shaInts_1.length = 0; shaInts_2.length = 0; shaInts_3.length = 0; sha256_1 = Sha256.hash(input.value()); sha256_2 = Sha256.hash(sha256_1); sha256_3 = Sha256.hash(sha256_2); for (let g = 0; g < 63; g = g + 2) { let pI = parseInt(sha256_1.substr(g, 2), 16); shaInts_1.push(pI); } for (let g = 0; g < 63; g = g + 2) { let pI = parseInt(sha256_2.substr(g, 2), 16); shaInts_2.push(pI); } for (let g = 0; g < 63; g = g + 2) { let pI = parseInt(sha256_3.substr(g, 2), 16); shaInts_3.push(pI); } createMusic(); waitMusic = false; createP(sha256_1, 4, 20); createP(shaInts_1, 4, 20); createP(notesA2play); createP(notesB2play); createP(notesC2play); var j = 0; for (let i = 0; i < 6; i++) { square1[j] = shaInts_1[i]; j++; } j = 0; for (let i = 6; i < 12; i++) { square2[j] = shaInts_1[i]; j++; } j = 0; for (let i = 12; i < 18; i++) { square3[j] = shaInts_1[i]; j++; } j = 0; for (let i = 18; i < 24; i++) { square4[j] = shaInts_1[i]; j++; } j = 0; for (let i = 24; i < 30; i++) { square5[j] = shaInts_1[i]; j++; } j = 0; for (let i = 30; i < 32; i++) { hotSpot[j] = shaInts_1[i]; j++; } squaresArray = [square1, square2, square3, square4, square5]; sortSquares(); renderSquares(); } function sortSquares() { let j = 0; for (let h = 256; h >= 0; h--) { for (let i = 0; i < 5; i++) { if (squaresArray[i][5] == h) { arraysSorted[j] = squaresArray[i]; j++; } } } hotSpot[0] = shaInts_1[30]; hotSpot[1] = shaInts_1[31]; } function renderSquares() { for (let i = 0; i < 5; i++) { let redAmt = arraysSorted[i][0]; let grnAmt = arraysSorted[i][1]; let bluAmt = arraysSorted[i][2]; let centerRx = arraysSorted[i][3] * 2; let centerRy = arraysSorted[i][4] * 2; let sqRadius = arraysSorted[i][5]; let sqSize = arraysSorted[i][5] * 2; let sqColor = color(redAmt, grnAmt, bluAmt); let xMap = map(centerRx, 0, 511, sqRadius, width - sqRadius); let yMap = map(centerRy, 0, 511, sqRadius, height - sqRadius); fill(sqColor); rect(xMap, yMap, sqSize, sqSize); } fill(0); let hSx = hotSpot[0] * 2; let hSy = hotSpot[1] * 2; let hSxMap = map(hSx, 0, 511, 15, width - 15); let hSyMap = map(hSy, 0, 511, 15, height - 15); ellipse(hSxMap, hSyMap, 30, 30); } function createMusic() { for (let i = 0; i < 16; i++) { numbersA[i] = shaInts_1[i]; numbersD[i] = shaInts_1[i + 16]; } for (let i = 0; i < 16; i++) { numbersB[i] = shaInts_2[i]; numbersE[i] = shaInts_2[i + 16]; } for (let i = 0; i < 16; i++) { numbersC[i] = shaInts_3[i]; numbersF[i] = shaInts_3[i + 16]; } for (let i = 0; i < numCroNotes; i++) { let divBy16 = floor(floor(numbersA[i] / 16)); notesA2play[i] = noteArray[divBy16]; } for (let i = 0; i < numCroNotes; i++) { let divBy16 = floor(floor(numbersB[i] / 16)); notesB2play[i] = noteArray[divBy16]; } for (let i = 0; i < numCroNotes; i++) { let divBy16 = floor(floor(numbersC[i] / 16)); notesC2play[i] = noteArray[divBy16]; } } function startMusic() { if (waitMusic == false) { goMusic = true; } } var wtpCount = 0; function draw() { if (goMusic == true) { if (timeCount % 40 == 0) { wingTip.play(); wtpCount++; let wtpVolume = random(0.80, 1.0); wingTip.setVolume(wtpVolume); } if (arrangeCount < 9) { if (timeCount % 10 == 0) { jamOn1(notesA2play[noteCount]); noteCount++; arrangeCount++; // Measures 1 - 2 } } else if (arrangeCount < 16) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } else if (arrangeCount < 25) { if (timeCount % 10 == 0) { jamOn2(notesA2play[noteCount]); noteCount++; arrangeCount++; // Measures 3 - 4 } } else if (arrangeCount < 32) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } else if (arrangeCount < 41) { if (timeCount % 10 == 0) { jamOn1(notesB2play[noteCount]); noteCount++; arrangeCount++; // Measures 5 - 6 } } else if (arrangeCount < 48) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } else if (arrangeCount < 57) { if (timeCount % 10 == 0) { jamOn2(notesA2play[noteCount]); noteCount++; arrangeCount++; // Measures 7 - 8 } } else if (arrangeCount < 64) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } else if (arrangeCount < 77) { if (timeCount % 10 == 0) { jamOn2(notesC2play[noteCount]); noteCount++; arrangeCount++; // Measures 9 - 10 } } else if (arrangeCount < 80) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } else if (arrangeCount < 89) { if (timeCount % 10 == 0) { jamOn1(notesA2play[noteCount]); noteCount++; arrangeCount++; // Measures 11 - 12 } } else if (arrangeCount < 96) { if (timeCount % 10 == 0) { arrangeCount++; } noteCount = 0; } timeCount++; if (arrangeCount >= 96) { arrangeCount = 0; goMusic = false; timeCount = 0; noteCount = 0; } } } function jcOsc() { osc1 = new p5.SawOsc(); osc2 = new p5.SawOsc(); osc3 = new p5.SawOsc(); osc1Env = new p5.Envelope(); osc2Env = new p5.Envelope(); osc3Env = new p5.Envelope(); osc1Env.setADSR(0.001, 0.010, 0.30, 1.2); osc2Env.setADSR(0.001, 0.010, 0.30, 1.2); osc3Env.setADSR(0.001, 0.010, 0.30, 1.2); osc1Env.setRange(0.53, 0); osc2Env.setRange(0.53, 0); osc3Env.setRange(0.30, 0); reverb1 = new p5.Reverb(); reverb2 = new p5.Reverb(); reverb3 = new p5.Reverb(); reverb1.process(osc1, 1.73, 1.6); reverb2.process(osc2, 1.73, 1.6); reverb3.process(osc3, 1.73, 1.6); reverb1.amp(1.10); reverb2.amp(1.10); reverb3.amp(1.10); osc1.amp(osc1Env); osc2.amp(osc2Env); osc3.amp(osc3Env); osc1.start(); osc2.start(); osc3.start(); } function jamOn1(xnote) { note = xnote; osc1Freq = midiToFreq(note); osc2Freq = midiToFreq(note); osc1.freq(osc1Freq); osc2.freq(osc2Freq * 1.003); osc1Env.play(); osc2Env.play(); } function jamOn2(xnote) { note = xnote; osc1Freq = midiToFreq(note); osc2Freq = midiToFreq(note); osc3Freq = midiToFreq(note); osc1.freq(osc1Freq); osc2.freq(osc2Freq * 1.003); osc3.freq(osc3Freq * 1.497); osc1Env.play(); osc2Env.play(); osc3Env.play(); } function touchStarted() { if (getAudioContext().state !== 'running') { getAudioContext().resume(); } } class Sha256 { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /*SHA-256(FIPS 180-4)implementation in JavaScript (c) Chris Veness 2002-2018 */ /* MIT Licence */ /* www.movable-type.co.uk/scripts/sha256.html */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ static hash(msg, options) { const defaults = { msgFormat: 'string', outFormat: 'hex' }; const opt = Object.assign(defaults, options); switch (opt.msgFormat) { default: case 'string': msg = utf8Encode(msg); break; case 'hex-bytes': msg = hexBytesToString(msg); break; } const K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; const H = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; msg += String.fromCharCode(0x80); const l = msg.length / 4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length const N = Math.ceil(l / 16); // number of 16-integer (512-bit) blocks required to hold 'l' ints const M = new Array(N); // message M is N×16 array of 32-bit integers for (let i = 0; i < N; i++) { M[i] = new Array(16); for (let j = 0; j < 16; j++) { M[i][j] = (msg.charCodeAt(i * 64 + j * 4 + 0) << 24) | (msg.charCodeAt(i * 64 + j * 4 + 1) << 16) | (msg.charCodeAt(i * 64 + j * 4 + 2) << 8) | (msg.charCodeAt(i * 64 + j * 4 + 3) << 0); } } const lenHi = ((msg.length - 1) * 8) / Math.pow(2, 32); const lenLo = ((msg.length - 1) * 8) >>> 0; M[N - 1][14] = Math.floor(lenHi); M[N - 1][15] = lenLo; for (let i = 0; i < N; i++) { const W = new Array(64); for (let t = 0; t < 16; t++) W[t] = M[i][t]; for (let t = 16; t < 64; t++) { W[t] = (Sha256.σ1(W[t - 2]) + W[t - 7] + Sha256.σ0(W[t - 15]) + W[t - 16]) >>> 0; } let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7]; for (let t = 0; t < 64; t++) { const T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t]; const T2 = Sha256.Σ0(a) + Sha256.Maj(a, b, c); h = g; g = f; f = e; e = (d + T1) >>> 0; d = c; c = b; b = a; a = (T1 + T2) >>> 0; } H[0] = (H[0] + a) >>> 0; H[1] = (H[1] + b) >>> 0; H[2] = (H[2] + c) >>> 0; H[3] = (H[3] + d) >>> 0; H[4] = (H[4] + e) >>> 0; H[5] = (H[5] + f) >>> 0; H[6] = (H[6] + g) >>> 0; H[7] = (H[7] + h) >>> 0; } for (let h = 0; h < H.length; h++) H[h] = ('00000000' + H[h].toString(16)).slice(-8); const separator = opt.outFormat == 'hex-w' ? ' ' : ''; return H.join(separator); function utf8Encode(str) { try { return new TextEncoder().encode(str, 'utf-8').reduce((prev, curr) => prev + String.fromCharCode(curr), ''); } catch (e) { return unescape(encodeURIComponent(str)); } } function hexBytesToString(hexStr) { const str = hexStr.replace(' ', ''); return str === '' ? '' : str.match(/.{2}/g).map(byte => String.fromCharCode(parseInt(byte, 16))).join(''); } } static ROTR(n, x) { return (x >>> n) | (x << (32 - n)); } static Σ0(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); } static Σ1(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); } static σ0(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x >>> 3); } static σ1(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x >>> 10); } static Ch(x, y, z) { return (x & y) ^ (~x & z); } static Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } }