From 038bced80497d5daf99d30184aa6db1267750cc3 Mon Sep 17 00:00:00 2001 From: Keerthana-A-V Date: Tue, 30 Nov 2021 22:25:05 +0530 Subject: [PATCH] upvote --- BIG TECHS AND THEIR DOMINANCE.html | 7 +- Biography of Aishwarya Sheoran.html | 5 - Biography of Alexander Lukashenko.html | 5 - Biography of Kamala Harris.html | 5 - Biography of Rishi Kapoor.html | 5 - Biography of Sachin Pilot.html | 5 - ... TRAIL' TO THE 'GRAVEYARD OF EMPIRES'.html | 7 +- FUTURE RESILIENCE A WORLD RE-EMERGING.html | 6 +- Farm Bills 2020.html | 7 +- INDIA'S COVID-19 SECOND WAVE.html | 7 +- Is RBI hurting India.html | 7 +- KEY TEST FOR EVERGRANDE.html | 19451 ++++++++-------- REGENERATING INTO SUSTAINABILITY.html | 19450 +++++++-------- ...DS LEGAL NOTICE FOR BREACH OF CONTRACT.htm | 7 +- THE BLOCKS OF SUSTENANCE.html | 19080 +++++++-------- ...ECHNOLOGICAL DEVELOPMENTS TODAY (2020).htm | 7 +- ...P-BIDEN FIRST PRESIDENTIAL DEBATE 2020.htm | 7 +- UNCOMMON PETS AND THEIR STORIES!.html | 7 +- ...DOES THE INDIAN ECONOMY NEED RIGHT NOW.htm | 7 +- ...A- US PARTNERSHIP WORK UNDER JOE BIDEN.htm | 7 +- WORLD'S FIRST FOUL AIR DEATH IN THE UK.htm | 7 +- ... TRADE DEAL TO BE SIGNED WITHOUT INDIA.htm | 7 +- ...and IRFC prepare for an IPO in the US.html | 9 +- content_collaboration1618935972531 (1).html | 7 - content_collaboration1621180117697.html | 7 +- 25 files changed, 30148 insertions(+), 27978 deletions(-) diff --git a/BIG TECHS AND THEIR DOMINANCE.html b/BIG TECHS AND THEIR DOMINANCE.html index 863a283..26cca7a 100644 --- a/BIG TECHS AND THEIR DOMINANCE.html +++ b/BIG TECHS AND THEIR DOMINANCE.html @@ -280,12 +280,7 @@
Revenue numbers for Big Tech

Profit margins peaked for the big techs despite the uncertainties created by the pandemic. Many companies experienced a precarious position but the tech industries shone throughout as they evolved opportunities for people. And since people were quarantined, digital platforms became a necessity for them. Hence, the digital curve accelerated with time without bouncing back, and it seems unstoppable. FAMAG, a well-known acronym for the big techs- Facebook, Apple, Microsoft, Amazon, and Google, showed a substantial increase in its revenues and profits during the second wave. People relied more on social media platforms during the pandemic because it helped them stay in touch with each other. Facebook, one of the many social networking sites, benefitted the most in the global turbulence. During the mid of the second Covid wave, its revenue increased by more than half, causing its profit to double. The tough times forced people to depend on online shopping, deliveries that helped giants like Amazon to perform even stronger. Its extending services, subscriptions, prime memberships, and third-party seller services have helped it to rise to new heights. Owing to the fact that people had to work from home, Microsoft Azure, a cloud computing platform, saw a surge in its services. Thus, it saw an increase in its revenues by one-fifth, which was much higher than any year. "Google is embracing remote work post-pandemic," said Google CEO Sundar Pichai, as its advertising and cloud computing services saw tremendous growth. Consequently, Alphabet, the parent company of Google, saw an increase in its revenues by one-third. Many companies believe that the work-from-home culture will remain prominent so that cloud service providers may continue to reap benefits even after the crisis. While the pandemic strictures were fatal for most economic sectors, the big techs are among the few winners.

Big Techs driving the US Stock Market

The stock market has dominated the global market since the beginning of the pandemic. The total value of the S&P 500 in 2020 stands at more than $7 trillion, accounting for almost one-fourth of the index's market capitalization. It is 20% less than before the pandemic. This reflects a shift to an increasingly technology-driven economy that is stimulated by the coronavirus outbreak. The big techs have seen their shares jump by 22% this year, with Amazon flying at 86%. Compared to 2020, the overall stock performance in the S&P 500 to date is less than 4% in 2021. The capitalization of the S&P 500 in 2015 has increased by $6 trillion. Out of this, $4 trillion is from the big six techs: Apple, Facebook, Microsoft, Alphabet, Amazon, and Netflix, up to two-thirds of the total profits in the S&P 500. Since 2015, the index has gained 56.5%. And after 23 March 2021, the index is up to 42.1%, which is approximately three-quarters of the gains of the previous five years. The holdings of major technology companies flew beyond other markets. After months of agony, the group staged a comeback with several tech giants who broke records in recent sessions. Additionally, beyond achieving its first high since January at the start of the week, Apple Inc.'s stock closed at a new high. These few companies can dominate their contemporary companies and set the rules of the global economy. This kind of constant dependency was never seen before. However, this kind of concentrated power is predicted to be dangerous.

Should the Big Techs be regulated?

The rise in shares and profitability of big tech is highlighting their monopoly in the market and triggering competitors. Allegedly, the big techs were trying to either subjugate their rivals or acquire them to grab the market, just like Facebook acquired WhatsApp and Instagram. In addition, they use local media information and publish it on their platform, for which a proper share of revenue is not given to the concerned authorities. The emerging companies are condemned by the big techs, as they manipulate market practices to increase their dominance and suppress their competitors. Like Facebook, it didn't offer sufficient data to show that the world's largest social network is a monopoly. Google has constantly made efforts to monopolize the mobile search market and its power over advertising technology. Play Store is seen as the default app store on Android, although users can also download apps from stores operated by companies like Amazon or Samsung or even install them. The company has loosely forced application developers to use its payment system for purchases made through the Google Play Store. Moreover, the company also paid higher to the app developers to prohibit them from removing their app from its Play Store. They must refrain from using their monopolistic power in a hyper-dominant market position to unlawfully leverage billions of added dollars from small companies' competitors and consumers beyond what should be paid. This illustrates how the concentration of power in a few hands leads to helplessness in the hands of the many.

-
Recent steps to tame Big Techs

Tech giants leading the world market have come under the suspicion of analysts. Glaring at the uncontrolled behavior of big techs, some countries have formulated rules and regulations. They have proposed legal restrictions on them to promote healthy competition among small, medium, and big companies. For instance, the European Union enacted the Digital Services Act (DSA) and the Digital Markets Act (DMA). These laws regulate intermediary services like social media platforms, internet providers, and e-commerce intermediaries. They also act as a sentry between companies and end-users to provide safety for users' data and create a healthy competitive environment among other companies. On the same lines to proscribe unlawful business practices in the U.S., Antitrust law was formulated in 1890. Under this law, several acts, like the Sherman Act, Free Trade Commission Act, and Clayton Act, promote fair competition and provide economic liberty. The U.S. president, Joe Biden, approved 72 recommendations and actions. These were executive orders to crack down on big tech and other sectors for anti-competitive practices. These orders will not only protect smaller competitors but also protect the consumer's personal information from exploitation. On the other hand, the Indian government had a tussle with Twitter for not appointing India-based nodal officers, compliance officers, and grievance redressal officers. On this issue, the new IT minister of India, Ashwini Vaishnaw, warned Twitter to follow the "law of the land."  Otherwise, Twitter could be held accountable for users' content, and lose protection under section 79 of the IT act. In addition, last year, the French finance ministry decided to levy a digital tax on big techs. The country adopted a "digital services tax" bill in July 2019 that imposed a 3% tax on digital turnover for companies whose annual sales exceed €750 million worldwide and €25 million across France. The American tech companies, Google, Amazon, Facebook, and Apple (GAFA) were asked to pay 3% tax on the annual turnover for the year 2020. The U.S. government retaliated and warned of levying up to 100% on $24 billion worth of French goods. Later, France agreed to delay the imposition of the digital tax on American companies. The tax was to be levied on 27 companies including, American, German, French, and Dutch companies. However, it has been delayed due to the political differences between the countries and concerns about the pandemic worldwide. The European Union and the U.S. laws should inspire and motivate other countries to frame laws to regulate the tech giants in their respective countries. This will provide opportunities for small businesses to thrive. Hence, it would help in curbing monopolies across the world.

- - Vote - - -
+
Recent steps to tame Big Techs

Tech giants leading the world market have come under the suspicion of analysts. Glaring at the uncontrolled behavior of big techs, some countries have formulated rules and regulations. They have proposed legal restrictions on them to promote healthy competition among small, medium, and big companies. For instance, the European Union enacted the Digital Services Act (DSA) and the Digital Markets Act (DMA). These laws regulate intermediary services like social media platforms, internet providers, and e-commerce intermediaries. They also act as a sentry between companies and end-users to provide safety for users' data and create a healthy competitive environment among other companies. On the same lines to proscribe unlawful business practices in the U.S., Antitrust law was formulated in 1890. Under this law, several acts, like the Sherman Act, Free Trade Commission Act, and Clayton Act, promote fair competition and provide economic liberty. The U.S. president, Joe Biden, approved 72 recommendations and actions. These were executive orders to crack down on big tech and other sectors for anti-competitive practices. These orders will not only protect smaller competitors but also protect the consumer's personal information from exploitation. On the other hand, the Indian government had a tussle with Twitter for not appointing India-based nodal officers, compliance officers, and grievance redressal officers. On this issue, the new IT minister of India, Ashwini Vaishnaw, warned Twitter to follow the "law of the land."  Otherwise, Twitter could be held accountable for users' content, and lose protection under section 79 of the IT act. In addition, last year, the French finance ministry decided to levy a digital tax on big techs. The country adopted a "digital services tax" bill in July 2019 that imposed a 3% tax on digital turnover for companies whose annual sales exceed €750 million worldwide and €25 million across France. The American tech companies, Google, Amazon, Facebook, and Apple (GAFA) were asked to pay 3% tax on the annual turnover for the year 2020. The U.S. government retaliated and warned of levying up to 100% on $24 billion worth of French goods. Later, France agreed to delay the imposition of the digital tax on American companies. The tax was to be levied on 27 companies including, American, German, French, and Dutch companies. However, it has been delayed due to the political differences between the countries and concerns about the pandemic worldwide. The European Union and the U.S. laws should inspire and motivate other countries to frame laws to regulate the tech giants in their respective countries. This will provide opportunities for small businesses to thrive. Hence, it would help in curbing monopolies across the world.

diff --git a/Biography of Aishwarya Sheoran.html b/Biography of Aishwarya Sheoran.html index ac4a4b7..6d43af4 100644 --- a/Biography of Aishwarya Sheoran.html +++ b/Biography of Aishwarya Sheoran.html @@ -360,11 +360,6 @@ - Upvote - -

- Upvote - -

- Upvote - -

- Upvote - -

- Upvote - -

Peace, art, and diversity

Afghanistan, also known as the 'Central Asian Roundabout', is a crossroads of unresolved paradoxes. The country retreated into peace after the Third Anglo-Afghan War, granting it a stable and peaceful period from 1929 to 1978. These almost 50 years saw culture, skills, and freedom flourishing again for travelers to take back exquisite artifacts, experiences, and the mystical presence of this land. The journey through these valleys tapered mountain folds along the Silk Route, came to be mapped as the Hippie Trail in the 1960s and 70s. Thousands of explorers, mostly in their youth traveled overland from Europe to India, and beyond. Some arrived from Australia through Southeast Asia and advanced back in the opposite direction, while others were trailing from Western Europe and passing through former Yugoslavia, Greece, Bulgaria, Turkey, Iran, Afghanistan, Pakistan, India, and Nepal. Hopping on a Volkswagen to cover these 11,000 kilometers, or trekking and hitchhiking into these life-changing experiences, the assurance of tranquility en-route, kept more coming, the 'Lonely Planet', is an example of a bi-product from the trail and the visionaries it birth. Afghanistan was one of the most popular destinations on the trail - from the folk instrumentality of sound to the authenticity found in traditional pottery, weaving, carvings, paintings, and every sublime expression of mastery for the exploring hearts. Some on the trail managed decent import-export businesses in handmade Afghani wedding coats and quality spices, but overall, the locals and foreigners both believed their major gains were freedom and love. This opening came with some early visitors and rulers instrumental in introducing social reforms and new ideologies to Afghanistan. From Nadir Shah's reign in 1929 to the end of Daud Khan's rule in 1978, many changes were introduced. Mohammed Zahir Shah (1933-1973) was the longest-serving ruler of Afghanistan, he reformed the army and extended diplomatic relations with many countries. A new constitution was adopted under Zahir's rule to promote National unity, and the Afghan National Independence Day known as the 'Jashn' joined the festivals collectively celebrated by the diverse tribes and ethnicities of the land. Afghanistan, in these years, was like any other western country with liberal ideologies that granted education for all and freedom for women to own their expression, including the right to vote, drive and travel; 40% of the doctors and 60% of the professors in Kabul University were women at the time. It was a time when everyone had a moral ambition of aspiration. The Afghans were very understanding and courteous towards foreign visitors, their influence was felt and absorbed strongly through aid, cultural programs, and growing tourism. However, the condition of Afghanistan at present does not bear any resemblance to what it was in the 1960s and 70s. It is claimed that Afghanistan is unconquerable and the 'Graveyard of Empires' for having witnessed the imperial powers submit to their end on this land time and again.

The battleground of empires

Afghanistan's geography has not only been an impediment, but also a lure for conquests owing to the country's strategic geopolitical location. Being at the heart of Asia that links six countries, the Afghan land shares borders with Uzbekistan, Turkmenistan in the North, Iran in the West, Pakistan in the South-East, and Tajikistan and  China in the North-East. Afghanistan is home to some of the highest mountains in the world, covering three-fourths of the country's region, occupied by the Hindu Kush at the Center and to the South, and the Pamir Mountains in the East. The Pamir Knot is in Badakhshan, Afghanistan, where the Hindu Kush, Tian Shan, Kunlun, Pamir, and the Himalayas all meet, serving as a natural wall preventing outsiders from entering, and also making connectivity difficult within the country. These labyrinths paired with guerrilla skills have always seen countrymen at an advantage in their fight against the invaders. This terrain, familiar to the local warlords has been enabling defining attacks on main supply roads, less defended bases, and small units that control communications; strengthening the operations by organizing themselves into small, highly mobile fighting groups advancing with unfaltering intent to protect their territory. Imperial arrogance seemed to have forgotten every time that the Afghan land has always been one of the warlords. Starting with the first Anglo-Afghan War in 1839, Russia sent an emissary to Kabul to offer support to the Afghans if they decided to attack Peshawar (an Afghan city that had come under British-supported Sikh rule), the British then sent a strong military force to defeat Afghan forces. British brute and careless provocation gave way to increasing resentment among Afghans, which grew into a rebellion in Kabul on December 23, 1841, after the British cut back subsidy to the Ghilzai tribes. The uprising had substantial support from the local population, and the British were coerced by the rebels to sign the Anglo-Afghan Treaty of 1919, also known as the Rawalpindi Treaty, it denied access to the British beyond the Khyber pass, while subsidies to the Afghans were stopped, it also served as a precursor to a growing friendship between Afghanistan and Russia. Afghanistan continued to be a vital point during the Cold War, with the Soviet Union in the North, and U.S. allies Iran and Pakistan in the East. Americans feared a Soviet push South, and both blocs knew Afghanistan was central to their hold, this saw more investments and infrastructural developments coming into the Nation from these opposing powers. Capitalism and Communism clashed, but paved the way for the acceptance of new ideologies and expression. The Afghans adopted Communism with the acceptance of Nur Mohammad Taraki as their leader and the new Communist President in 1978. A manifesto with some progressive reforms was introduced, however, this new governance foresaw the end of Islam and all mosques to be empty within a year. They were predominantly an atheist regime, and this did not work well with the rest of the Muslim population resisting the communists who were already lashing out with unregulated prison sentences and executions. Russians then decided to enter Afghanistan with military force to support the Afghan Communist Regime, this strengthened the resistance from the local Mujaheddin further. The U.S. then started supplying high-grade military supplies to the Mujaheddin through Pakistan to weaken the communists. The ensuing 10-year war has been "Russia's Vietnam," with the country sending in thousands of troops, spending millions, and eventually withdrawing. As with most empires that enter Afghanistan, too much blood and resources have them overstaying their demise. The Soviet-Afghan war became a humanitarian disaster for the disintegrating Soviet Union by the late 1980s. The decision to finally withdraw their forces was taken by Mikhail Gorbachev when he became the General Secretary of State in 1985, though more time was asked and he granted. The Geneva Accords were signed between USSR, U.S., and Pakistan on Russia's final withdrawal from Afghanistan in 1988. After the Russian Revolution, Afghanistan began to be known as "The Graveyard of the Empires." No foreign power in history has been able to maintain control in Afghanistan owing to its strict adherence to the Pashtunwali, its faith, strong patriotic ideology, and Afghanistan's difficult terrain. Afghans have a strong history of combat, not in the sense of frontlines and open battlefields, but guerrilla warfare. After The Russian forces withdrew, International aid continued to pour in, even from the Soviet Union, this led to growing conflicts and chaos internally, and the Taliban- orphans of the warring Blocs, emerged stronger.

-
Growing Turmoil

The rising of the Taliban appeared as a promise to end local corruption and war in the country, but the result was counterproductive. Gradually, the Taliban conquered several provinces in the Southern and Central parts of Afghanistan in 1994 and quickly extended their influence in the city of Kandahar, taking control of Herat in September 1995. The militant group developed enough strength to expand its control throughout the country. In September 1996, the Taliban attacked the residential areas of Kabul with the military support of Pakistan and financial support of Saudi Arabia. As a result, the Taliban emerged and took control of the capital Kabul by overthrowing the regime of President Burhanuddin Rabbani. They were also influenced to rename the country as the "Islamic Emirate of Afghanistan." The Taliban especially targeted civilians of the Hazara community or Shia Islamists. In 1998, the Taliban executed approximately four thousand civilians from this community and tortured many more in Mazar-E-Sharif. From 1996 to 2001, the Taliban took control over one-third area of Afghanistan, and their enforcement of Islamic laws resulted in a massacre against the Afghan people. The Taliban denied UN food supplies, destroyed thousands of homes, and burned vast areas of land in Afghanistan. The Taliban imposed a strict interpretation of Sharia law, which included punishments such as public executions and amputations of body parts. During that period, they banned all forms of entertainment, including television, the media, photography, cinema, painting, movies, music (except daf, a type of drum), etc. The group committed human rights violations, particularly against women, such as forbidding them from working outside, attending schools, coming outside of their home unless accompanied by a male member. By the end of 2000, the Taliban managed to control about 95% of the country while receiving continued resistance from Northern Alliances in the Panjshir Valley. After the 9/11 attack, the United States deposed the Taliban from power in Afghanistan in less than two months. Furthermore, the U.S. bombing and massive defections successfully blocked the Taliban and restricted them to a small region around Kunduz. In 2009, the counter insurrection accelerated with the decision by Barack Obama to send the U.S. troops to Afghanistan. After the U.S.-led forces overthrew the Taliban government, people made great strides in Afghanistan. And in August 2021, the Taliban regained power when the U.S. troops withdrew from Afghanistan. Following the fall of the capital Kabul, the Taliban re-captured Afghanistan on 15th August 2021. Afghan people were in fear of losing their liberty and these concerns are apparent, as the Taliban have already started imposing old restrictions. They have formulated dress and public behavior standards for women and prohibited their employment and movement in public places. They have also tortured journalists for covering protests in Kabul, they again made it compulsory for women to wear burqa outside their home, failing to do so would amount to harsh punishment, they also declared they would punish unmarried men and women if seen together. The Taliban are inspecting all the checkpoints, driving around heavily armed in pickup trucks and humvees. Thousands of people were seen racing to flee the country from the Kabul airport. The U.S. and some other nations sent military helicopters to evacuate their citizens and embassy personnel from Afghanistan. The militants moved inside the presidential palace in Kabul, declaring the restoration of the Taliban. The Afghan President also flew away as he asserted that he wanted to save Kabul from bloodshed. Half the population is hiding behind closed doors, and this is the new Afghanistan in 2021. Afghanistan's economy is at a standstill under the Taliban regime, with the country's internal banking system completely frozen. The Biden administration officially declared that any financial institutions' assets belonging to Afghanistan within the U.S. won't be made available to the Taliban. Similarly, the U.S. Federal Reserve and International Monetary Fund (IMF) have also frozen all of Afghanistan's foreign exchange reserves and their access to IMF resources to restrict the misuse of these funds by the Taliban. There's a crowd of local afghans outside the banks regularly as they are not allowing them to withdraw their money. People living there are at high risk due to poor health facilities, and the Taliban has banned the COVID-19 vaccination in the country. With no economic activity and zero financial sustainability, people are selling their household items to avoid starvation. The suffering for the Afghans seems indefinite. However, there are some people who are not scared of the terrible situation in Afghanistan and are trying to fight back and help however they can. Farhan Hotak, who not only helped his family flee from Afghanistan to Pakistan but many others in need too. At the age of 22, he first made sure that his family was safe and then he returned to help others. In addition, he is keeping a very keen eye on his crypto portfolio because the local currency has touched new lows. Although Afghanistan still works on a cash economy, his crypto gives him peace of mind during these unstable times.

- - Vote - - -
+
Growing Turmoil

The rising of the Taliban appeared as a promise to end local corruption and war in the country, but the result was counterproductive. Gradually, the Taliban conquered several provinces in the Southern and Central parts of Afghanistan in 1994 and quickly extended their influence in the city of Kandahar, taking control of Herat in September 1995. The militant group developed enough strength to expand its control throughout the country. In September 1996, the Taliban attacked the residential areas of Kabul with the military support of Pakistan and financial support of Saudi Arabia. As a result, the Taliban emerged and took control of the capital Kabul by overthrowing the regime of President Burhanuddin Rabbani. They were also influenced to rename the country as the "Islamic Emirate of Afghanistan." The Taliban especially targeted civilians of the Hazara community or Shia Islamists. In 1998, the Taliban executed approximately four thousand civilians from this community and tortured many more in Mazar-E-Sharif. From 1996 to 2001, the Taliban took control over one-third area of Afghanistan, and their enforcement of Islamic laws resulted in a massacre against the Afghan people. The Taliban denied UN food supplies, destroyed thousands of homes, and burned vast areas of land in Afghanistan. The Taliban imposed a strict interpretation of Sharia law, which included punishments such as public executions and amputations of body parts. During that period, they banned all forms of entertainment, including television, the media, photography, cinema, painting, movies, music (except daf, a type of drum), etc. The group committed human rights violations, particularly against women, such as forbidding them from working outside, attending schools, coming outside of their home unless accompanied by a male member. By the end of 2000, the Taliban managed to control about 95% of the country while receiving continued resistance from Northern Alliances in the Panjshir Valley. After the 9/11 attack, the United States deposed the Taliban from power in Afghanistan in less than two months. Furthermore, the U.S. bombing and massive defections successfully blocked the Taliban and restricted them to a small region around Kunduz. In 2009, the counter insurrection accelerated with the decision by Barack Obama to send the U.S. troops to Afghanistan. After the U.S.-led forces overthrew the Taliban government, people made great strides in Afghanistan. And in August 2021, the Taliban regained power when the U.S. troops withdrew from Afghanistan. Following the fall of the capital Kabul, the Taliban re-captured Afghanistan on 15th August 2021. Afghan people were in fear of losing their liberty and these concerns are apparent, as the Taliban have already started imposing old restrictions. They have formulated dress and public behavior standards for women and prohibited their employment and movement in public places. They have also tortured journalists for covering protests in Kabul, they again made it compulsory for women to wear burqa outside their home, failing to do so would amount to harsh punishment, they also declared they would punish unmarried men and women if seen together. The Taliban are inspecting all the checkpoints, driving around heavily armed in pickup trucks and humvees. Thousands of people were seen racing to flee the country from the Kabul airport. The U.S. and some other nations sent military helicopters to evacuate their citizens and embassy personnel from Afghanistan. The militants moved inside the presidential palace in Kabul, declaring the restoration of the Taliban. The Afghan President also flew away as he asserted that he wanted to save Kabul from bloodshed. Half the population is hiding behind closed doors, and this is the new Afghanistan in 2021. Afghanistan's economy is at a standstill under the Taliban regime, with the country's internal banking system completely frozen. The Biden administration officially declared that any financial institutions' assets belonging to Afghanistan within the U.S. won't be made available to the Taliban. Similarly, the U.S. Federal Reserve and International Monetary Fund (IMF) have also frozen all of Afghanistan's foreign exchange reserves and their access to IMF resources to restrict the misuse of these funds by the Taliban. There's a crowd of local afghans outside the banks regularly as they are not allowing them to withdraw their money. People living there are at high risk due to poor health facilities, and the Taliban has banned the COVID-19 vaccination in the country. With no economic activity and zero financial sustainability, people are selling their household items to avoid starvation. The suffering for the Afghans seems indefinite. However, there are some people who are not scared of the terrible situation in Afghanistan and are trying to fight back and help however they can. Farhan Hotak, who not only helped his family flee from Afghanistan to Pakistan but many others in need too. At the age of 22, he first made sure that his family was safe and then he returned to help others. In addition, he is keeping a very keen eye on his crypto portfolio because the local currency has touched new lows. Although Afghanistan still works on a cash economy, his crypto gives him peace of mind during these unstable times.

diff --git a/FUTURE RESILIENCE A WORLD RE-EMERGING.html b/FUTURE RESILIENCE A WORLD RE-EMERGING.html index 756f7fb..0807798 100644 --- a/FUTURE RESILIENCE A WORLD RE-EMERGING.html +++ b/FUTURE RESILIENCE A WORLD RE-EMERGING.html @@ -282,11 +282,7 @@
Authentic Nuances

The pandemic has made its presence felt globally, but the effects of this presence have been distributed unevenly. Some social minorities have had to brave more severe consequences, while others have had ancient wisdom and a humanitarian foresight to keep the torch ignited for the collective. Either way, the spotlight that these two parallel pillars deserve was granted to them by the pandemic. The ancient knowledge and harmony that some indigenous cultures have managed to preserve can offer great insights and solutions to handle many practical and emotional vulnerabilities of these times and beyond by not denying them, but rather turning the same vulnerabilities into the strength of trusting what is not familiar, and respecting that which has always been there for us to nurture and be nurtured by. The pandemic brought online, circles and gatherings offered by and for the indigenous communities to connect more deep and organic with the world community, so both the sides could benefit equally from the sharing. Many spontaneous initiatives to contradict the limitations of the crisis were born, to only grow from here. In Cachar district in the state of Assam, India. A small group of boys aged 14-25, shared a common interest in cricket, and used WhatsApp group for scheduling their matches, but, when the lock-down was imposed, they came to know about issues being faced by people of this area, embarking them on a mission to assist their community. The group first organized funds by sharing links to UPI-based applications like Google Pay at local medical and supply stores. In the beginning, they delivered 50-60 packets of ration to the needy, in some time, with better management and recruitment of volunteers they began to reach a large number of people. Further, they were supported by the elders of their community, and till today they are working to provide resources to the needy, daily wage earners, migrants, tea garden laborers, and beggars in their area. A small change of attitude can light up the entire society. By the same token, in remote villages of Odisha state when weaver communities were impacted by the pandemic and their income was forced to closure, they utilized their weaving skills in mask manufacturing, these masks were made with 'Ikat', a distinctive fabric dyeing method consisting of natural fabric that creates a beautiful design on clothes, a tradition being passed on through generations by these weaver communities in Odisha. Moreover, these masks were sustainable, handmade, and reusable, and with the help of PARINAMA and RYTHM Foundation, they were able to fulfill an order of 30000 masks for QNET. This not only supported a particular community, but gave natural and sustainable protection to many during the pandemic. David Sanchez from Colombia worked with his team "Colombia help" teaching the countryside people self-dependency for survival - like cooking, skill development, and production for a living, he is also helping them to export their products now. Linda Kemoli from Kenya began spreading Covid-19 awareness at its onset, as most of them did not have an internet connection and not even electricity, she trained the ones who had access to it so they could teach others through visual activities explaining to them how the world was before the pandemic, during this pandemic, and what they can do to better prepare for a world after the pandemic. These interactions also provided everyone participating with the opportunity to share insight and exchange opinions, traditional knowledge and technological advancements that can be merged for better living in times to come. These are just some of the authentic nuances from the many that are shaping more self-reliant lives for an equitable movement forward.

Alternative Economics

Economics for a common good is the core motivation fueling new economic models. "Generative Economy" - introduced by Marjorie Kelly, is a living socio-economic design aligned with solutions focused on the cradle to grave approach. Rich in biodiversity and not limited by mono-culture, generative economy's main purpose is to sustain fair and just conditions that benefit all layers by organizing the structure and objective of the living body or community as a whole. Regenerative economics begins with giving respect to source capital - sun and earth. Though complex in the fact that humans are the driving force, regenerative economy has the ability to operate at a consciousness higher than other non-holistic and linear systems, given to its deeper understanding of ecological patterns and principles while integrating valuable wisdom from traditions in present systems to meet changing dynamics and supporting balanced participation and collaboration. According to Charles Eisenstein, 'Scarcity is built into the money system,' in Sacred Economics, he talks about how we didn't earn anything that keeps us alive, the air we breathe is a gift, and so is life itself, and therefore, the most important skill we can own, is gratitude. With grace we can continue giving and receiving, in a gift economy - the surplus that we have is shared with who needs it, there is no competition or insecurities to feel any lack. A Circular Economy is based on the 3R's- Reduce, Reuse and Recycle; where resource use is minimized and reuse of products is maximized to create a close-loop system. It's confirmed! Current systems of money are insufficient and lob-sided. Progress has been restricting itself with different faces of ruling classes, bureaucracy and governance. And now these restrictions are shifting. Decentralized financial (DeFi) systems are already enabling alternatives a step closer towards a fair economic environment. According to the P2P Foundation, "Society is shifting from a system based on value created in market through labor and capital, to a system that recognizes broader value streams such as social and creative value generated online. The rise of new types of value generated by commoners working outside of typical market structures - is forcing us to go beyond the simple equation of price = value." A truly developed society does not cater only to the needs of a few, but to the needs of the society as a unit. Doughnut economy envisions economic humanity, it is said to be far more inclusive than other parallel economies and is being discussed by governments worldwide. The doughnut economy model consists of two rings where one forms a social foundation so that nobody is left out and the other one is a ceiling ring to make sure that it doesn't overshoot planetary boundaries. The doughnut is at the core. Doughnut economics proposes an economic mindset that's fit for the challenges of the present world, It's this very creative thinking that makes this unique and logical; drawing insights from various complex economies and beliefs, it presents itself as a comprehensive model, focused on the big picture, and not limited to a Gross Domestic Product (GDP). Bhutan, a small kingdom in the Himalayas was far more foresighted than the rest of the world to mandate in 2008, (GNH) Gross National Happiness as a measure instead of GDP, for National Development. Today it is the only carbon-negative country in the world.

Healing Collaborations

Collaboration can be experienced as a science and art of life, 'we are not constant, we are an arrow in flight, the sum of the angles of change', and this dynamic constant is a product of our interactions within and out, human conditions are forever transforming, so to live without a sense of being grounded with respect to inter-dependability stiffens individual and collective purpose and well-being. The pandemic has displayed some positive patterns in re-building a sense of collaborative responsibilities, bringing the world closer into understanding our short-comings and strengths to build on for a resilient future. From art and cultural collaborations on-line to exploring International support mechanisms and relationships; collaborative efforts continue to keep hope ignited, one lamp, torch, lighter at a time. It has been noticed that cross-collaboration leads to a decrease in the collective healthcare risks that are difficult to manage independently. Sharing experiences, ideas, and knowledge, accelerates productive ties and implementation, and providing support standards increases the impact of research in development, while building mutual trust and understanding. A holistic approach to any given problem always serves better, specially when it's the collective well-being in concern. The pandemic has been another reminder that self-satiation can never satisfy sustainably, and neither can wealth ever be health, and our environment and local communities are not independent of one another. As the Greek philosopher, Socrates once said, "A part of us can never be well unless the whole is well." Therefore, the only way forward from all the ignorance so far, is to see the solutions through together. Flexible leadership, inclusive cooperation, equality, and just decision-making are all important for healthy resilience planning, which should become central to communities, Nations and all fellow beings. 'Resilience planning', includes personal responsibility in making the right decisions and supporting positive collaborations. Our relationship with the environment and how we interact with what we produce and consume are all important for future resilience. With as many solutions to disease as we have found, we must also nurture a healthy relationship with our bodies - physical, emotional and spiritual, as this is the core collaboration that is going to raise the collective consciousness to empower all other collaborative efforts more, and these preventive solutions will continue strengthening resilience further. Many initiatives are encouraging free learning sessions, sharing spaces and dialogues to assist this movement of self-empowerment, while raising funds to direct them where they are needed. Collaborative efforts at every layer, from the grassroots up are re-aligning our world into one we create and nurture, assuaging insecurities and vulnerabilities along the way, claiming the human rights that have gone neglected, while dissolving outdated oppressive structures now frail and crumbling.

-
A Space for Creative Expression

Art is the most beautiful expression of human emotions and this space for freedom to express raises collective consciousness, it gives the most vulnerable sections of society a voice and an element of respect, while serving as a channel for learning and healing to tackle many issues like violence, harassment, etc. The pandemic has created many safe spaces for alternate voices and these discussions and sharing allow more creative solutions to real-world contradictions. For many, art has been the breath they could count on to keep serving the suffocating reality that was erupting around them. Many doctors began to create an alternate reality on their canvases and screens. "At a time when viruses can seem unknowable and scary, turning them into decorations, and including non-pathogenic viruses, is a reminder that viruses are only another part of the natural world." - Ed Hutchinson, lead of the molecular virology group at MRC. Sharing spaces allows us to go beyond our comfort zones, exchange thoughts, and cooperate, even if sometimes only possible electronically; this has been made possible by the generous spirit of thousands of individuals who read, watch, listen to, and respect artistic expression, particularly now. This outpouring of support reflects that a creative life is vital to society. It is essential to seek purpose in life during such moments, and self-expression and self-exploration through any creative channel creates a fluid space for new ideas to create new experiences. Keeping in mind the inalienable role of expression for serving human rights, UNESCO has issued guidelines to promote and protect freedom of expression through electronic mediums to encourage regional art and culture, individual artists, and cultural activists. Many artists have been performing to raise funds during the pandemic, while children are now strumming and drumming with their parents more. The spaces created by unscheduling and absent rush hour distractions are finding the rhythm for unbound expression that our global family is always there to celebrate.

- - Vote - - +
A Space for Creative Expression

Art is the most beautiful expression of human emotions and this space for freedom to express raises collective consciousness, it gives the most vulnerable sections of society a voice and an element of respect, while serving as a channel for learning and healing to tackle many issues like violence, harassment, etc. The pandemic has created many safe spaces for alternate voices and these discussions and sharing allow more creative solutions to real-world contradictions. For many, art has been the breath they could count on to keep serving the suffocating reality that was erupting around them. Many doctors began to create an alternate reality on their canvases and screens. "At a time when viruses can seem unknowable and scary, turning them into decorations, and including non-pathogenic viruses, is a reminder that viruses are only another part of the natural world." - Ed Hutchinson, lead of the molecular virology group at MRC. Sharing spaces allows us to go beyond our comfort zones, exchange thoughts, and cooperate, even if sometimes only possible electronically; this has been made possible by the generous spirit of thousands of individuals who read, watch, listen to, and respect artistic expression, particularly now. This outpouring of support reflects that a creative life is vital to society. It is essential to seek purpose in life during such moments, and self-expression and self-exploration through any creative channel creates a fluid space for new ideas to create new experiences. Keeping in mind the inalienable role of expression for serving human rights, UNESCO has issued guidelines to promote and protect freedom of expression through electronic mediums to encourage regional art and culture, individual artists, and cultural activists. Many artists have been performing to raise funds during the pandemic, while children are now strumming and drumming with their parents more. The spaces created by unscheduling and absent rush hour distractions are finding the rhythm for unbound expression that our global family is always there to celebrate.

diff --git a/Farm Bills 2020.html b/Farm Bills 2020.html index b6947c4..9b81ec0 100644 --- a/Farm Bills 2020.html +++ b/Farm Bills 2020.html @@ -377,12 +377,7 @@ The crucial modifications pursue to free farming markets from the restrictions f Local markets, where farmers sell their products directly in their local areas. When they didn’t get a sufficient price for their product they moved to APMC( Agricultural produce market committee) which was established by the government in every state. These are also called Sarkari mandis. In India, there are 6500 Sarkari mandis. For Sarkari mandi, the government issues licenses to middlemen, Commission agents, or traders. Farmers take their produce to Sarkari mandi, where the quality test for those products is performed and then the auction is done according to the quality. However, traders buy those products from farmers. There is a tax amount to be paid by the traders is 0.528%, Which differs from state to state. Another option for the farmers is MSP (minimum support price) Where farmers sell their produce directly to the government in an amount fixed by the government. According to the farm bill, the state comment says that whichever crops are sold in private mandi will be tax-free. However, the tax that the government receives in APMC Will not be received by them. In some states like Punjab, the tax received by APMC Is more than 3500 crores. - However, according to the farmer leaders, it has been said that if the private market is initiated then in the beginning there will be selling of products in an APMC because there will be zero tax in the private market. This may be beneficial for farmers in the beginning but APMC will be inefficient in the long run then this will be removed. When the private market holds the entire market, the government will lose its control over the market which will result in the entry of low-scale farmers. Apart from this, according to the farmers, MSP has not specified anywhere in the recent Bill passed that this will be carried in the future also. This leads farmers to doubt and question that will it be continued further. Moreover, Every year FCI that stores crops are spoiled due to the MSP facility. According, to the farmers, the government is not taking appropriate action to increase the storage facility for crops. So the farmer demands to give guarantee for MSP to be continued further, also sufficient storage for crops and most focusing to ensure that the crops will not be sold in less than MSP in the private market.

- - Vote - - -
+ However, according to the farmer leaders, it has been said that if the private market is initiated then in the beginning there will be selling of products in an APMC because there will be zero tax in the private market. This may be beneficial for farmers in the beginning but APMC will be inefficient in the long run then this will be removed. When the private market holds the entire market, the government will lose its control over the market which will result in the entry of low-scale farmers. Apart from this, according to the farmers, MSP has not specified anywhere in the recent Bill passed that this will be carried in the future also. This leads farmers to doubt and question that will it be continued further. Moreover, Every year FCI that stores crops are spoiled due to the MSP facility. According, to the farmers, the government is not taking appropriate action to increase the storage facility for crops. So the farmer demands to give guarantee for MSP to be continued further, also sufficient storage for crops and most focusing to ensure that the crops will not be sold in less than MSP in the private market.

diff --git a/INDIA'S COVID-19 SECOND WAVE.html b/INDIA'S COVID-19 SECOND WAVE.html index c181a76..de6f89e 100644 --- a/INDIA'S COVID-19 SECOND WAVE.html +++ b/INDIA'S COVID-19 SECOND WAVE.html @@ -354,12 +354,7 @@ The repercussions of lockdown on the economic structure will persist even after There are numerous solutions and safety nets measures that might facilitate curbing the situation. Firstly, the protection of employees needs to be primary. Statistics on a way to shield oneself need to be provided, along with safety necessities, including hand sanitizers also to be provided. Further, medical insurance which incorporates paid sick leave needs to be extended to all employees. This suggests that the authorities and employers need to pay for the remedy of employees and also make sure no loss of earnings for sick leaves. Secondly, unemployment advantages need to be paid to aid employees whose earnings are misplaced or dwindled because of the outbreak. This is important for ensuring that employees do not bear the financial shock. Some unemployment insurances exist in India, including in Punjab, however aren't prolonged to entrepreneurs and tech-employees. This might be in the form of its health and monetary crises. The authorities should create access to the public distribution system. This device has already proven powerful in Tamil Nadu and can be replicated in the rest of the country. -The government of India and the technology companies that function right here should begin considering the workers who hold this country together. Ideally, the experts or megalomaniacs should have addressed the people about anticipated health emergencies and have planned ways to build a capable health infrastructure. Solutions like UBI transfers can help briefly plug the holes of an otherwise broken social security system. However, it might not be a long-time answer. The country has tried to control the crisis, but this is only the beginning. The world is bracing for a much larger disaster, as should we – developing sturdy social protection nets for marginalized and vulnerable people is one manner to put together for the vagaries and unpredictability of the approaching months. To finish up, the need of the hour is to feature plans to bolster our healthcare system, boost the assets and convert all pains and sufferings as the potential energy to fix this nation.

- - Vote - - -
+The government of India and the technology companies that function right here should begin considering the workers who hold this country together. Ideally, the experts or megalomaniacs should have addressed the people about anticipated health emergencies and have planned ways to build a capable health infrastructure. Solutions like UBI transfers can help briefly plug the holes of an otherwise broken social security system. However, it might not be a long-time answer. The country has tried to control the crisis, but this is only the beginning. The world is bracing for a much larger disaster, as should we – developing sturdy social protection nets for marginalized and vulnerable people is one manner to put together for the vagaries and unpredictability of the approaching months. To finish up, the need of the hour is to feature plans to bolster our healthcare system, boost the assets and convert all pains and sufferings as the potential energy to fix this nation.

diff --git a/Is RBI hurting India.html b/Is RBI hurting India.html index 8a15ca5..9942c20 100644 --- a/Is RBI hurting India.html +++ b/Is RBI hurting India.html @@ -348,12 +348,7 @@ With that history of banking performance, the Reserve Bank of India should not b
No innovation in Indian banking sector

In an advanced economy, the Reserve Bank of India is probably the only central bank that decides how many branches a bank can open and what ATMs can do. It also decides whether SMS is required to be sent after a transaction. Small operational decisions like what products to offer, what rates to offer, which usually should be performed inside the bank, all must be approved by the Reserve Bank of India. To grow innovation, creative destruction is an essential condition. Newer forms of banking must emerge in marketplaces freely and offer better and efficient services challenging the incumbent. Thus, newer and multiple choices are offered to customers that would force the incumbent to make rapid changes in response. If the incumbent is too slow and becomes fossilized, it must fail. If failure is not permitted, then the system freezes, and innovation stops. The Western World sees massive innovations in the banking sector driven by common people like independent third-party ATMs in stores and petrol stations, pure online banks, narrow functional banks, and the multitude of credit and investment products, none of which go to the Central Bank for approval. In India, if Times Group launches an innocuous international money transfer service using Bollywood actor, Amitabh Bachchan as a brand ambassador, it gets shut down instantly by the RBI. -With a past record of being an agency actively opposing innovation Reserve Bank of India asphyxiates innovation due to a lack of other oxygen Experimentation Space. Our entrepreneurs should be making consistent innovations and newer experiments, challenging the status quo all the time. But the dark monster in the room called the Reserve Bank of India will never allow it, as two young entrepreneurs in Bangalore found out after being thrown into prison for creating a cash dispensing machine for their own customers. How can the soul of society even tolerate the consideration of a prison sentence for entrepreneurs wanting to improve customer/consumer experience? It is anything but fair that entrepreneurs of India go to prison for innovation in the blink of an eye, when western entrepreneurs can bump even the sitting President of their country, off their platform. It takes no genius to recognize that if bureaucrats are put in charge of innovation, we get neither innovation nor stability. As, is evident by the decay of the banking sector in the peak years of Indian economic growth. From 2000 to 2020, when the Indian Economy was making ravishing strides, our banks were getting saddled with bad debts almost to the point of extinction unless taxpayer's money bailed them out. How ironic? To reclaim the innovative spirit of Indian society in the banking sector, the Reserve Bank of India has to step back. We are a culture that has been provided leading innovation for centuries, and even now our people run the largest corporations in the world with a finesse that is unrivaled. Our nationalization experiment has failed. Our 1935 Central Bank experiment has failed. It is time to recognize the obvious. India needs to rediscover the inner spirit in the banking and finance sector. We need to rejuvenate our souls. We need ordinary people to be empowered by freedoms that can permit creative destruction and experimentation space without fear or favor. If a choice needs to be made between the Reserve Bank of India and Cryptocurrencies, the decision is very obvious.

- - Vote - - -
+With a past record of being an agency actively opposing innovation Reserve Bank of India asphyxiates innovation due to a lack of other oxygen Experimentation Space. Our entrepreneurs should be making consistent innovations and newer experiments, challenging the status quo all the time. But the dark monster in the room called the Reserve Bank of India will never allow it, as two young entrepreneurs in Bangalore found out after being thrown into prison for creating a cash dispensing machine for their own customers. How can the soul of society even tolerate the consideration of a prison sentence for entrepreneurs wanting to improve customer/consumer experience? It is anything but fair that entrepreneurs of India go to prison for innovation in the blink of an eye, when western entrepreneurs can bump even the sitting President of their country, off their platform. It takes no genius to recognize that if bureaucrats are put in charge of innovation, we get neither innovation nor stability. As, is evident by the decay of the banking sector in the peak years of Indian economic growth. From 2000 to 2020, when the Indian Economy was making ravishing strides, our banks were getting saddled with bad debts almost to the point of extinction unless taxpayer's money bailed them out. How ironic? To reclaim the innovative spirit of Indian society in the banking sector, the Reserve Bank of India has to step back. We are a culture that has been provided leading innovation for centuries, and even now our people run the largest corporations in the world with a finesse that is unrivaled. Our nationalization experiment has failed. Our 1935 Central Bank experiment has failed. It is time to recognize the obvious. India needs to rediscover the inner spirit in the banking and finance sector. We need to rejuvenate our souls. We need ordinary people to be empowered by freedoms that can permit creative destruction and experimentation space without fear or favor. If a choice needs to be made between the Reserve Bank of India and Cryptocurrencies, the decision is very obvious.

diff --git a/KEY TEST FOR EVERGRANDE.html b/KEY TEST FOR EVERGRANDE.html index a74e902..329afd2 100644 --- a/KEY TEST FOR EVERGRANDE.html +++ b/KEY TEST FOR EVERGRANDE.html @@ -315,12 +315,8 @@
Root cause of its downfall

The world stock markets never foresaw Evergrande facing such a big crisis. Problems started looming over the grande company last year when the real estate sector was adversely affected by the pandemic, increasing Evergrande's debts like never before. The crisis affected the company to such an extent that the company had to send a warning to its investors. It was facing a liquidity crunch, and it had left them without money to pay off its debts. Later, when Evergrande was questioned, it denied warning any of its investors. Another big reason for its downfall was its expansionary moves spread in a wide range of different categories like vehicles, food parks, groceries, dairy products, and many more. Their proliferation reportedly caused the company to continually borrow money from the market and eventually going into debt. Their situation worsened when China launched a crackdown to curb down the borrowing costs of developers and placed ceilings on their debt. As a result, the Bank of China had drafted three red lines for property developers that affected them severely. And the companies that failed to comply with those lines were not allowed to borrow from banks. Under the pressure of complying with these guidelines, Evergrande sold many unfinished projects to consumers that brought down the property rates to a huge extent. This cash crunch and the inability to pay back its investors has thrown serious questions at the company that was once the biggest real estate company in China. As of September 23, 2021, an interest payment of about 120 million dollars to the bondholders was unpaid. Similarly, according to some reports, 669 million dollars in coupon payments are due by the end of 2021.

Upshot of Evergrande's collapse

The contagion risk that has taken place in the sprawling real estate developer is concerning the Chinese economy. There are several consequences of Evergrande's probable collapse. Firstly, the banking industry would be triggered and it could lead to an adverse affair in China. According to Mattie Bekink from the Economist Intelligence Unit (EIU), "Evergrande owes money to around 121 financial firms and 171 domestic banks." Therefore, if the company defaults, there will be economic contagion risk for the banking sectors of China. Also, if Evergrande falls flat, banks may be forced to lend a minimal amount that could lead to a situation of credit crunch. Secondly, many companies around the globe are also at risk because they share business relations with Evergrande. In addition, construction and design firms are also at risk of inducing major losses that could lead them to a state of liquidation. This may also demoralize foreign investors who could have their business relations with China. Thirdly, the contagion in the property sector will badly affect the home buyers, investors, and suppliers. People have already paid deposits for their under-construction properties and plots. Thus, they could potentially lose their investment after the collapse. In September 2021, the homebuyers and investors protested for their repayment of loans. Reportedly, around a hundred investors broke out at Evergrande's headquarters in Shenzhen. These traumas are contributing to an overall slowdown in China's economic growth. According to a report from Barclays, the company has an estimated 800 unfinished projects across China, and as many as 1.6 million people are waiting to move into their new homes. Possibilities are that Evergrande's binge on the debt will threaten China's economy.

Will the government intervene to redeem Evergrande?

The piling debts are becoming unmanageable for the company. The fallout of Evergrande is approaching a financial mess and weakening the economy of China. According to the Bank of America, Evergrande sold about 200,000 housing units and did not hand them over to their buyers. A disorderly collapse of Evergrande can lead to financial instability as the company solely holds about 14% of GDP in China. People who have invested money in the properties committed by Evergrande are completely devastated owing to their ruined hopes of a house. When the investors demanded to return their investments and financial products, the founder of Evergrande tried to reassure them that their homes would be ready on time. The investors believe that the government will guarantee the delivery of the houses. Some analysts believe that the government will have to invest money in Evergrande to continue the leftover construction and sell those residential properties to pay off the debts. And with the financial support of the government, the company could become a part of SOEs (state-owned enterprises). Speculations are regarding the nationalization of Evergrande, restructuring of the company into separate entities backed by the SOEs. To stop the deepening crisis of Evergrande, people hope for the government to intervene and limit the collapse of the real estate conglomerate. These speculations became uncertain when the authorities asked the local government to prepare for Evergrande's potential downfall. There are speculations that the World Bank will limit large amounts of loans to companies in the future. However, some economists believe that the bank and bank holders will probably lose money if Evergrande restructures its debt, knowing that Beijing has the sources to avoid a credit crunch in China. The clampdowns caught the attention of a Swiss central bank that volunteered to monitor the situation. The Chairman of Swiss National Bank, Thomas Jordan, said: "Evergrande should not be dismissed as a local problem because these issues could unsettle markets." In September 2021, the People's Bank of China injected liquidity for three sessions in a row. It is thus fueling expectations that the government would want to save Evergrande.

-
Global market reception

Most of the major market indexes have been falling due to concerns about Evergrande Group and the impact it could have on China's economy as well as the global economy. Evergrande Group shares have dropped lowest this time in the past 11 years. Shares in the company's property management and electric car divisions have also fallen a lot as the real estate conglomerate struggles to raise the millions of dollars needed to pay interest to its lenders over the next few days. Evergrande's shares will continue to drop because no other option appears to be helping the firm alleviate its liquidity problems. According to sources, there are still unresolved questions about what the company will do in the event of a restructuring. Investors are making assumptions on whether the Chinese government will assist in bailing out the company, whose collapse will undoubtedly have an impact on the global economy. Investors are concerned that the collapse of the real estate behemoth would pose significant risks to China's financial stability and economic growth. Many are concerned that losses will force bondholders to sell other investments or sell risky securities to raise cash, harming markets that appear unrelated. Some analysts are even referring to it as China's Lehman Brothers moment, relating to the 2008 collapse of the US investment bank that clearly indicated the onset of the global financial crisis. However, the likelihood of such broader financial consequences is low. If the firm is unable to pay its dues, there will be tremors in the foreign financial markets, but they will be short-lived. Evergrande has $18 billion in impending foreign-currency bonds, with Chinese banks holding the majority of them. China's banking system is said to be capable of absorbing defaults, with an annual profit of 1.9 trillion Yuan and reserves of 5.4 trillion Yuan against bad loans. Analysts believe that even a chaotic developer collapse would just have a minor global impact. Even if it were the first of many property developers to fail in China, it is anticipated that a policy failure would be required to create a major slowdown in the country's economy. Many feel that the crypto market's recent slump was impacted by the same, as investors scrambled to liquidate their crypto holdings. The Chinese Central Bank, on the other hand, has poured 120 billion Yuan ($19 billion) into the financial sector in the hopes of rescuing Evergrande. China's default on Evergrande might be costly, and many experts forecasted that the country would do all in its power to prevent the company from failing, and their predictions tend to come true. With Evergrande considering a bailout, the crypto market could see a bearish to bullish trend flip. China has begun to inject stimulus into its financial system, and the end of September might see the bulls return to the crypto market. Because the crypto market has historically been bullish in the fourth quarter, the start of October could assist the market in resurging to its bullish ways, as it did in August.

- - Vote - - -
+
Global market reception

Most of the major market indexes have been falling due to concerns about Evergrande Group and the impact it could have on China's economy as well as the global economy. Evergrande Group shares have dropped lowest this time in the past 11 years. Shares in the company's property management and electric car divisions have also fallen a lot as the real estate conglomerate struggles to raise the millions of dollars needed to pay interest to its lenders over the next few days. Evergrande's shares will continue to drop because no other option appears to be helping the firm alleviate its liquidity problems. According to sources, there are still unresolved questions about what the company will do in the event of a restructuring. Investors are making assumptions on whether the Chinese government will assist in bailing out the company, whose collapse will undoubtedly have an impact on the global economy. Investors are concerned that the collapse of the real estate behemoth would pose significant risks to China's financial stability and economic growth. Many are concerned that losses will force bondholders to sell other investments or sell risky securities to raise cash, harming markets that appear unrelated. Some analysts are even referring to it as China's Lehman Brothers moment, relating to the 2008 collapse of the US investment bank that clearly indicated the onset of the global financial crisis. However, the likelihood of such broader financial consequences is low. If the firm is unable to pay its dues, there will be tremors in the foreign financial markets, but they will be short-lived. Evergrande has $18 billion in impending foreign-currency bonds, with Chinese banks holding the majority of them. China's banking system is said to be capable of absorbing defaults, with an annual profit of 1.9 trillion Yuan and reserves of 5.4 trillion Yuan against bad loans. Analysts believe that even a chaotic developer collapse would just have a minor global impact. Even if it were the first of many property developers to fail in China, it is anticipated that a policy failure would be required to create a major slowdown in the country's economy. Many feel that the crypto market's recent slump was impacted by the same, as investors scrambled to liquidate their crypto holdings. The Chinese Central Bank, on the other hand, has poured 120 billion Yuan ($19 billion) into the financial sector in the hopes of rescuing Evergrande. China's default on Evergrande might be costly, and many experts forecasted that the country would do all in its power to prevent the company from failing, and their predictions tend to come true. With Evergrande considering a bailout, the crypto market could see a bearish to bullish trend flip. China has begun to inject stimulus into its financial system, and the end of September might see the bulls return to the crypto market. Because the crypto market has historically been bullish in the fourth quarter, the start of October could assist the market in resurging to its bullish ways, as it did in August.

+ @@ -341,9353 +337,10118 @@ Logout + Upvote + + + +

+ + + - - - - - - - - - + + + + + - - \ No newline at end of file + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += e; + } + + return [H0, H1, H2, H3, H4]; + }; + + // Package private blocksize + SHA1._blocksize = 16; + + SHA1._digestsize = 20; + })(); + + //Added to make PKBDF2 work + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.HMAC = function (hasher, message, key, options) { + // Convert to byte arrays + if (message.constructor == String) + message = UTF8.stringToBytes(message); + if (key.constructor == String) key = UTF8.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize * 4) + key = hasher(key, { + asBytes: true, + }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize * 4; i++) { + okey[i] ^= 0x5c; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher( + okey.concat( + hasher(ikey.concat(message), { + asBytes: true, + }) + ), + { + asBytes: true, + } + ); + + return options && options.asBytes + ? hmacbytes + : options && options.asString + ? Binary.bytesToString(hmacbytes) + : util.bytesToHex(hmacbytes); + }; + })(); + + //crypto-sha256-hmac.js + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + + function ascii_to_hexa(str) { + var arr1 = []; + for (var n = 0, l = str.length; n < l; n++) { + var hex = Number(str.charCodeAt(n)).toString(16); + arr1.push(hex); + } + return arr1.join(""); + } + + (typeof Crypto == "undefined" || !Crypto.util) && + (function () { + var d = (window.Crypto = {}), + k = (d.util = { + rotl: function (b, a) { + return (b << a) | (b >>> (32 - a)); + }, + rotr: function (b, a) { + return (b << (32 - a)) | (b >>> a); + }, + endian: function (b) { + if (b.constructor == Number) + return (k.rotl(b, 8) & 16711935) | (k.rotl(b, 24) & 4278255360); + for (var a = 0; a < b.length; a++) b[a] = k.endian(b[a]); + return b; + }, + randomBytes: function (b) { + for (var a = []; b > 0; b--) + a.push(Math.floor(Math.random() * 256)); + return a; + }, + bytesToWords: function (b) { + for (var a = [], c = 0, e = 0; c < b.length; c++, e += 8) + a[e >>> 5] |= (b[c] & 255) << (24 - (e % 32)); + return a; + }, + wordsToBytes: function (b) { + for (var a = [], c = 0; c < b.length * 32; c += 8) + a.push((b[c >>> 5] >>> (24 - (c % 32))) & 255); + return a; + }, + bytesToHex: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push((b[c] >>> 4).toString(16)), + a.push((b[c] & 15).toString(16)); + return a.join(""); + }, + hexToBytes: function (b) { + for (var a = [], c = 0; c < b.length; c += 2) + a.push(parseInt(b.substr(c, 2), 16)); + return a; + }, + bytesToBase64: function (b) { + for (var a = [], c = 0; c < b.length; c += 3) + for ( + var e = (b[c] << 16) | (b[c + 1] << 8) | b[c + 2], p = 0; + p < 4; + p++ + ) + c * 8 + p * 6 <= b.length * 8 + ? a.push( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( + (e >>> (6 * (3 - p))) & 63 + ) + ) + : a.push("="); + return a.join(""); + }, + base64ToBytes: function (b) { + for ( + var b = b.replace(/[^A-Z0-9+\/]/gi, ""), a = [], c = 0, e = 0; + c < b.length; + e = ++c % 4 + ) + e != 0 && + a.push( + (("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf( + b.charAt(c - 1) + ) & + (Math.pow(2, -2 * e + 8) - 1)) << + (e * 2)) | + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf( + b.charAt(c) + ) >>> + (6 - e * 2)) + ); + return a; + }, + }), + d = (d.charenc = {}); + d.UTF8 = { + stringToBytes: function (b) { + return g.stringToBytes(unescape(encodeURIComponent(b))); + }, + bytesToString: function (b) { + return decodeURIComponent(escape(g.bytesToString(b))); + }, + }; + var g = (d.Binary = { + stringToBytes: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push(b.charCodeAt(c) & 255); + return a; + }, + bytesToString: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push(String.fromCharCode(b[c])); + return a.join(""); + }, + }); + })(); + (function () { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary, + c = [ + 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, + 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, + 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, + 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, + 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, + 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, + 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, + 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, + 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, + 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, + 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, + 2756734187, 3204031479, 3329325298, + ], + e = (d.SHA256 = function (b, c) { + var f = k.wordsToBytes(e._sha256(b)); + return c && c.asBytes + ? f + : c && c.asString + ? a.bytesToString(f) + : k.bytesToHex(f); + }); + e._sha256 = function (a) { + a.constructor == String && (a = b.stringToBytes(a)); + var e = k.bytesToWords(a), + f = a.length * 8, + a = [ + 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, + 2600822924, 528734635, 1541459225, + ], + d = [], + g, + m, + r, + i, + n, + o, + s, + t, + h, + l, + j; + e[f >> 5] |= 128 << (24 - (f % 32)); + e[(((f + 64) >> 9) << 4) + 15] = f; + for (t = 0; t < e.length; t += 16) { + f = a[0]; + g = a[1]; + m = a[2]; + r = a[3]; + i = a[4]; + n = a[5]; + o = a[6]; + s = a[7]; + for (h = 0; h < 64; h++) { + h < 16 + ? (d[h] = e[h + t]) + : ((l = d[h - 15]), + (j = d[h - 2]), + (d[h] = + (((l << 25) | (l >>> 7)) ^ + ((l << 14) | (l >>> 18)) ^ + (l >>> 3)) + + (d[h - 7] >>> 0) + + (((j << 15) | (j >>> 17)) ^ + ((j << 13) | (j >>> 19)) ^ + (j >>> 10)) + + (d[h - 16] >>> 0))); + j = (f & g) ^ (f & m) ^ (g & m); + var u = + ((f << 30) | (f >>> 2)) ^ + ((f << 19) | (f >>> 13)) ^ + ((f << 10) | (f >>> 22)); + l = + (s >>> 0) + + (((i << 26) | (i >>> 6)) ^ + ((i << 21) | (i >>> 11)) ^ + ((i << 7) | (i >>> 25))) + + ((i & n) ^ (~i & o)) + + c[h] + + (d[h] >>> 0); + j = u + j; + s = o; + o = n; + n = i; + i = (r + l) >>> 0; + r = m; + m = g; + g = f; + f = (l + j) >>> 0; + } + a[0] += f; + a[1] += g; + a[2] += m; + a[3] += r; + a[4] += i; + a[5] += n; + a[6] += o; + a[7] += s; + } + return a; + }; + e._blocksize = 16; + e._digestsize = 32; + })(); + (function () { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary; + d.HMAC = function (c, e, d, g) { + e.constructor == String && (e = b.stringToBytes(e)); + d.constructor == String && (d = b.stringToBytes(d)); + d.length > c._blocksize * 4 && + (d = c(d, { + asBytes: !0, + })); + for ( + var f = d.slice(0), d = d.slice(0), q = 0; + q < c._blocksize * 4; + q++ + ) + (f[q] ^= 92), (d[q] ^= 54); + c = c( + f.concat( + c(d.concat(e), { + asBytes: !0, + }) + ), + { + asBytes: !0, + } + ); + return g && g.asBytes + ? c + : g && g.asString + ? a.bytesToString(c) + : k.bytesToHex(c); + }; + })(); + + /*! + * Random number generator with ArcFour PRNG + * + * NOTE: For best results, put code like + * + * in your main HTML document. + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + (function () { + // Constructor function of Global SecureRandom object + var sr = (window.SecureRandom = function () {}); + + // Properties + sr.state; + sr.pool; + sr.pptr; + sr.poolCopyOnInit; + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + sr.poolSize = 256; + + // --- object methods --- + + // public method + // ba: byte array + sr.prototype.nextBytes = function (ba) { + var i; + if ( + window.crypto && + window.crypto.getRandomValues && + window.Uint8Array + ) { + try { + var rvBytes = new Uint8Array(ba.length); + window.crypto.getRandomValues(rvBytes); + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte() ^ rvBytes[i]; + return; + } catch (e) { + alert(e); + } + } + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte(); + }; + + // --- static methods --- + + // Mix in the current time (w/milliseconds) into the pool + // NOTE: this method should be called from body click/keypress event handlers to increase entropy + sr.seedTime = function () { + sr.seedInt(new Date().getTime()); + }; + + sr.getByte = function () { + if (sr.state == null) { + sr.seedTime(); + sr.state = sr.ArcFour(); // Plug in your RNG constructor here + sr.state.init(sr.pool); + sr.poolCopyOnInit = []; + for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr) + sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr]; + sr.pptr = 0; + } + // TODO: allow reseeding after first request + return sr.state.next(); + }; + + // Mix in a 32-bit integer into the pool + sr.seedInt = function (x) { + sr.seedInt8(x); + sr.seedInt8(x >> 8); + sr.seedInt8(x >> 16); + sr.seedInt8(x >> 24); + }; + + // Mix in a 16-bit integer into the pool + sr.seedInt16 = function (x) { + sr.seedInt8(x); + sr.seedInt8(x >> 8); + }; + + // Mix in a 8-bit integer into the pool + sr.seedInt8 = function (x) { + sr.pool[sr.pptr++] ^= x & 255; + if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize; + }; + + // Arcfour is a PRNG + sr.ArcFour = function () { + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + return new Arcfour(); + }; + + // Initialize the pool with junk if needed. + if (sr.pool == null) { + sr.pool = new Array(); + sr.pptr = 0; + var t; + if ( + window.crypto && + window.crypto.getRandomValues && + window.Uint8Array + ) { + try { + // Use webcrypto if available + var ua = new Uint8Array(sr.poolSize); + window.crypto.getRandomValues(ua); + for (t = 0; t < sr.poolSize; ++t) sr.pool[sr.pptr++] = ua[t]; + } catch (e) { + alert(e); + } + } + while (sr.pptr < sr.poolSize) { + // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + sr.pool[sr.pptr++] = t >>> 8; + sr.pool[sr.pptr++] = t & 255; + } + sr.pptr = Math.floor(sr.poolSize * Math.random()); + sr.seedTime(); + // entropy + var entropyStr = ""; + // screen size and color depth: ~4.8 to ~5.4 bits + entropyStr += + window.screen.height * window.screen.width * window.screen.colorDepth; + entropyStr += + window.screen.availHeight * + window.screen.availWidth * + window.screen.pixelDepth; + // time zone offset: ~4 bits + var dateObj = new Date(); + var timeZoneOffset = dateObj.getTimezoneOffset(); + entropyStr += timeZoneOffset; + // user agent: ~8.3 to ~11.6 bits + entropyStr += navigator.userAgent; + // browser plugin details: ~16.2 to ~21.8 bits + var pluginsStr = ""; + for (var i = 0; i < navigator.plugins.length; i++) { + pluginsStr += + navigator.plugins[i].name + + " " + + navigator.plugins[i].filename + + " " + + navigator.plugins[i].description + + " " + + navigator.plugins[i].version + + ", "; + } + var mimeTypesStr = ""; + for (var i = 0; i < navigator.mimeTypes.length; i++) { + mimeTypesStr += + navigator.mimeTypes[i].description + + " " + + navigator.mimeTypes[i].type + + " " + + navigator.mimeTypes[i].suffixes + + ", "; + } + entropyStr += pluginsStr + mimeTypesStr; + // cookies and storage: 1 bit + entropyStr += + navigator.cookieEnabled + typeof sessionStorage + typeof localStorage; + // language: ~7 bit + entropyStr += navigator.language; + // history: ~2 bit + entropyStr += window.history.length; + // location + entropyStr += window.location; + + var entropyBytes = Crypto.SHA256(entropyStr, { + asBytes: true, + }); + for (var i = 0; i < entropyBytes.length; i++) { + sr.seedInt8(entropyBytes[i]); + } + } + })(); + + //ripemd160.js + /* + CryptoJS v3.1.2 + code.google.com/p/crypto-js + (c) 2009-2013 by Jeff Mott. All rights reserved. + code.google.com/p/crypto-js/wiki/License + */ + /** @preserve + (c) 2012 by Cédric Mesnil. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + // Constants table + var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, + 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, + 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, + 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, + ]; + var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, + 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, + 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, + 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11, + ]; + var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, + 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, + 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, + 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, + ]; + var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, + 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, + 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, + 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11, + ]; + + var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]; + var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]; + + var bytesToWords = function (bytes) { + var words = []; + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - (b % 32)); + } + return words; + }; + + var wordsToBytes = function (words) { + var bytes = []; + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - (b % 32))) & 0xff); + } + return bytes; + }; + + var processBlock = function (H, M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + // Swap + M[offset_i] = + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00); + } + + // Working variables + var al, bl, cl, dl, el; + var ar, br, cr, dr, er; + + ar = al = H[0]; + br = bl = H[1]; + cr = cl = H[2]; + dr = dl = H[3]; + er = el = H[4]; + // Computation + var t; + for (var i = 0; i < 80; i += 1) { + t = (al + M[offset + zl[i]]) | 0; + if (i < 16) { + t += f1(bl, cl, dl) + hl[0]; + } else if (i < 32) { + t += f2(bl, cl, dl) + hl[1]; + } else if (i < 48) { + t += f3(bl, cl, dl) + hl[2]; + } else if (i < 64) { + t += f4(bl, cl, dl) + hl[3]; + } else { + // if (i<80) { + t += f5(bl, cl, dl) + hl[4]; + } + t = t | 0; + t = rotl(t, sl[i]); + t = (t + el) | 0; + al = el; + el = dl; + dl = rotl(cl, 10); + cl = bl; + bl = t; + + t = (ar + M[offset + zr[i]]) | 0; + if (i < 16) { + t += f5(br, cr, dr) + hr[0]; + } else if (i < 32) { + t += f4(br, cr, dr) + hr[1]; + } else if (i < 48) { + t += f3(br, cr, dr) + hr[2]; + } else if (i < 64) { + t += f2(br, cr, dr) + hr[3]; + } else { + // if (i<80) { + t += f1(br, cr, dr) + hr[4]; + } + t = t | 0; + t = rotl(t, sr[i]); + t = (t + er) | 0; + ar = er; + er = dr; + dr = rotl(cr, 10); + cr = br; + br = t; + } + // Intermediate hash value + t = (H[1] + cl + dr) | 0; + H[1] = (H[2] + dl + er) | 0; + H[2] = (H[3] + el + ar) | 0; + H[3] = (H[4] + al + br) | 0; + H[4] = (H[0] + bl + cr) | 0; + H[0] = t; + }; + + function f1(x, y, z) { + return x ^ y ^ z; + } + + function f2(x, y, z) { + return (x & y) | (~x & z); + } + + function f3(x, y, z) { + return (x | ~y) ^ z; + } + + function f4(x, y, z) { + return (x & z) | (y & ~z); + } + + function f5(x, y, z) { + return x ^ (y | ~z); + } + + function rotl(x, n) { + return (x << n) | (x >>> (32 - n)); + } + + function ripemd160(message) { + var H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + var m = bytesToWords(message); + + var nBitsLeft = message.length * 8; + var nBitsTotal = message.length * 8; + + // Add padding + m[nBitsLeft >>> 5] |= 0x80 << (24 - (nBitsLeft % 32)); + m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00); + + for (var i = 0; i < m.length; i += 16) { + processBlock(H, m, i); + } + + // Swap endian + for (var i = 0; i < 5; i++) { + // Shortcut + var H_i = H[i]; + + // Swap + H[i] = + (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + var digestbytes = wordsToBytes(H); + return digestbytes; + } + + // Upstream 'BigInteger' here: + // Original Author: http://www-cs-students.stanford.edu/~tjw/jsbn/ + // Follows 'jsbn' on Github: https://github.com/jasondavies/jsbn + // Review and Testing: https://github.com/cryptocoinjs/bigi/ + /*! + * Basic JavaScript BN library - subset useful for RSA encryption. v1.4 + * + * Copyright (c) 2005 Tom Wu + * All Rights Reserved. + * BSD License + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + * + * Copyright Stephan Thomas + * Copyright pointbiz + */ + + (function () { + // (public) Constructor function of Global BigInteger object + var BigInteger = (window.BigInteger = function BigInteger(a, b, c) { + if (!(this instanceof BigInteger)) return new BigInteger(a, b, c); + + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + }); + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = (canary & 0xffffff) == 0xefcafe; + + // return new, unset BigInteger + function nbi() { + return new BigInteger(null); + } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + if (j_lm && navigator.appName == "Microsoft Internet Explorer") { + BigInteger.prototype.am = am2; + dbits = 30; + } else if (j_lm && navigator.appName != "Netscape") { + BigInteger.prototype.am = am1; + dbits = 26; + } else { + // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = (1 << dbits) - 1; + BigInteger.prototype.DV = 1 << dbits; + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; + var BI_RC = new Array(); + var rr, vv; + rr = "0".charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = "a".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = "A".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { + return BI_RM.charAt(n); + } + + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return c == null ? -1 : c; + } + + // return bigint initialized to value + function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; + } + + // (protected) copy this to r + BigInteger.prototype.copyTo = function (r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + }; + + // (protected) set from integer value x, -DV <= x < DV + BigInteger.prototype.fromInt = function (x) { + this.t = 1; + this.s = x < 0 ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + }; + + // (protected) set from string and radix + BigInteger.prototype.fromString = function (s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; + // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = k == 8 ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = x >> (this.DB - sh); + } else this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) clamp off excess high words + BigInteger.prototype.clamp = function () { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + }; + + // (protected) r = this << n*DB + BigInteger.prototype.dlShiftTo = function (n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + }; + + // (protected) r = this >> n*DB + BigInteger.prototype.drShiftTo = function (n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + }; + + // (protected) r = this << n + BigInteger.prototype.lShiftTo = function (n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + }; + + // (protected) r = this >> n + BigInteger.prototype.rShiftTo = function (n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + }; + + // (protected) r = this - a + BigInteger.prototype.subTo = function (a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = c < 0 ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + }; + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyTo = function (a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + }; + + // (protected) r = this^2, r != this (HAC 14.16) + BigInteger.prototype.squareTo = function (r) { + var x = this.abs(); + var i = (r.t = 2 * x.t); + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ( + (r[i + x.t] += x.am( + i + 1, + 2 * x[i], + r, + 2 * i + 1, + c, + x.t - i - 1 + )) >= x.DV + ) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + }; + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + BigInteger.prototype.divRemTo = function (m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = q == null ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = + r[--i] == y0 + ? this.DM + : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { + // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + }; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + BigInteger.prototype.invDigit = function () { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return y > 0 ? this.DV - y : -y; + }; + + // (protected) true iff this is even + BigInteger.prototype.isEven = function () { + return (this.t > 0 ? this[0] & 1 : this.s) == 0; + }; + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + BigInteger.prototype.exp = function (e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + }; + + // (public) return string representation in given radix + BigInteger.prototype.toString = function (b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, + m = false, + r = "", + i = this.t; + var p = this.DB - ((i * this.DB) % k); + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : "0"; + }; + + // (public) -this + BigInteger.prototype.negate = function () { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + }; + + // (public) |this| + BigInteger.prototype.abs = function () { + return this.s < 0 ? this.negate() : this; + }; + + // (public) return + if this > a, - if this < a, 0 if equal + BigInteger.prototype.compareTo = function (a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return this.s < 0 ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; + }; + + // (public) return the number of bits in "this" + BigInteger.prototype.bitLength = function () { + if (this.t <= 0) return 0; + return ( + this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) + ); + }; + + // (public) this mod a + BigInteger.prototype.mod = function (a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + }; + + // (public) this^e % m, 0 <= e < 2^32 + BigInteger.prototype.modPowInt = function (e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); + }; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + // Extended JavaScript BN functions, required for RSA private ops. + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; + } + + var lowprimes = [ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, + 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, + 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, + 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, + 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, + 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, + 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, + 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + ]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + // (protected) return x s.t. r^x < DV + BigInteger.prototype.chunkSize = function (r) { + return Math.floor((Math.LN2 * this.DB) / Math.log(r)); + }; + + // (protected) convert to radix string + BigInteger.prototype.toRadix = function (b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + }; + + // (protected) convert from radix string + BigInteger.prototype.fromRadix = function (s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) alternate constructor + BigInteger.prototype.fromNumber = function (a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) + // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) + this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= (1 << t) - 1; + else x[0] = 0; + this.fromString(x, 256); + } + }; + + // (protected) r = this op a (bitwise) + BigInteger.prototype.bitwiseTo = function (a, op, r) { + var i, + f, + m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + }; + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = c < 0 ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + }; + + // (protected) this *= n, this >= 0, 1 < n < DV + BigInteger.prototype.dMultiply = function (n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + }; + + // (protected) this += n << w words, this >= 0 + BigInteger.prototype.dAddOffset = function (n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + }; + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyLowerTo = function (a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) + r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + }; + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyUpperTo = function (a, n, r) { + --n; + var i = (r.t = this.t + a.t - n); + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + }; + + // (protected) this % n, n < 2^26 + BigInteger.prototype.modInt = function (n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = this.s < 0 ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + }; + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + BigInteger.prototype.millerRabin = function (t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + }; + + // (public) + BigInteger.prototype.clone = function () { + var r = nbi(); + this.copyTo(r); + return r; + }; + + // (public) return value as integer + BigInteger.prototype.intValue = function () { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + }; + + // (public) return value as byte + BigInteger.prototype.byteValue = function () { + return this.t == 0 ? this.s : (this[0] << 24) >> 24; + }; + + // (public) return value as short (assumes DB>=16) + BigInteger.prototype.shortValue = function () { + return this.t == 0 ? this.s : (this[0] << 16) >> 16; + }; + + // (public) 0 if this == 0, 1 if this > 0 + BigInteger.prototype.signum = function () { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + }; + + // (public) convert to bigendian byte array + BigInteger.prototype.toByteArray = function () { + var i = this.t, + r = new Array(); + r[0] = this.s; + var p = this.DB - ((i * this.DB) % 8), + d, + k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + }; + + BigInteger.prototype.equals = function (a) { + return this.compareTo(a) == 0; + }; + BigInteger.prototype.min = function (a) { + return this.compareTo(a) < 0 ? this : a; + }; + BigInteger.prototype.max = function (a) { + return this.compareTo(a) > 0 ? this : a; + }; + + // (public) this & a + function op_and(x, y) { + return x & y; + } + BigInteger.prototype.and = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + }; + + // (public) this | a + function op_or(x, y) { + return x | y; + } + BigInteger.prototype.or = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + }; + + // (public) this ^ a + function op_xor(x, y) { + return x ^ y; + } + BigInteger.prototype.xor = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + }; + + // (public) this & ~a + function op_andnot(x, y) { + return x & ~y; + } + BigInteger.prototype.andNot = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + }; + + // (public) ~this + BigInteger.prototype.not = function () { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + }; + + // (public) this << n + BigInteger.prototype.shiftLeft = function (n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; + }; + + // (public) this >> n + BigInteger.prototype.shiftRight = function (n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; + }; + + // (public) returns index of lowest 1-bit (or -1 if none) + BigInteger.prototype.getLowestSetBit = function () { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + }; + + // (public) return number of set bits + BigInteger.prototype.bitCount = function () { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + }; + + // (public) true iff nth bit is set + BigInteger.prototype.testBit = function (n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return this.s != 0; + return (this[j] & (1 << n % this.DB)) != 0; + }; + + // (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, + is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { + // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + }; + + // (public) 1/this % m (HAC 14.61) + BigInteger.prototype.modInverse = function (m) { + var ac = m.isEven(); + if (this.signum() === 0) throw new Error("division by zero"); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + while (d.compareTo(m) >= 0) d.subTo(m, d); + while (d.signum() < 0) d.addTo(m, d); + return d; + }; + + // (public) this^e + BigInteger.prototype.pow = function (e) { + return this.exp(e, new NullExp()); + }; + + // (public) gcd(this,a) (HAC 14.54) + BigInteger.prototype.gcd = function (a) { + var x = this.s < 0 ? this.negate() : this.clone(); + var y = a.s < 0 ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + }; + + // (public) test primality with certainty >= 1-.5^t + BigInteger.prototype.isProbablePrime = function (t) { + var i, + x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + }; + + // JSBN-specific extension + + // (public) this^2 + BigInteger.prototype.square = function () { + var r = nbi(); + this.squareTo(r); + return r; + }; + + // NOTE: BigInteger interfaces not implemented in jsbn: + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Copyright Stephan Thomas (start) --- // + // https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js + // BigInteger monkey patching + BigInteger.valueOf = nbv; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + if (ba.length) { + if (ba[0] == 0) { + ba = ba.slice(1); + } + return ba.map(function (v) { + return v < 0 ? v + 256 : v; + }); + } else { + // Empty array, nothing to do + return ba; + } + }; + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + BigInteger.fromByteArrayUnsigned = function (ba) { + if (!ba.length) { + return ba.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Converts big integer to signed byte representation. + * + * The format for this value uses a the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + BigInteger.prototype.toByteArraySigned = function () { + var val = this.abs().toByteArrayUnsigned(); + var neg = this.compareTo(BigInteger.ZERO) < 0; + + if (neg) { + if (val[0] & 0x80) { + val.unshift(0x80); + } else { + val[0] |= 0x80; + } + } else { + if (val[0] & 0x80) { + val.unshift(0x00); + } + } + + return val; + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + // Copyright Stephan Thomas (end) --- // + + // ****** REDUCTION ******* // + + // Modular reduction using "classic" algorithm + var Classic = (window.Classic = function Classic(m) { + this.m = m; + }); + Classic.prototype.convert = function (x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + }; + Classic.prototype.revert = function (x) { + return x; + }; + Classic.prototype.reduce = function (x) { + x.divRemTo(this.m, null, x); + }; + Classic.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + Classic.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + + // Montgomery reduction + var Montgomery = (window.Montgomery = function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + }); + // xR mod m + Montgomery.prototype.convert = function (x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + }; + // x/R mod m + Montgomery.prototype.revert = function (x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + }; + // x = x/R mod m (HAC 14.32) + Montgomery.prototype.reduce = function (x) { + while (x.t <= this.mt2) + // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = + (j * this.mpl + + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & + x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = "xy/R mod m"; x,y != r + Montgomery.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = "x^2/R mod m"; x != r + Montgomery.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + + // A "null" reducer + var NullExp = (window.NullExp = function NullExp() {}); + NullExp.prototype.convert = function (x) { + return x; + }; + NullExp.prototype.revert = function (x) { + return x; + }; + NullExp.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + }; + NullExp.prototype.sqrTo = function (x, r) { + x.squareTo(r); + }; + + // Barrett modular reduction + var Barrett = (window.Barrett = function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + }); + Barrett.prototype.convert = function (x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + }; + Barrett.prototype.revert = function (x) { + return x; + }; + // x = x mod m (HAC 14.42) + Barrett.prototype.reduce = function (x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = x*y mod m; x,y != r + Barrett.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = x^2 mod m; x != r + Barrett.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + })(); + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + //ellipticcurve.js + /*! + * Basic Javascript Elliptic Curve implementation + * Ported loosely from BouncyCastle's Java EC code + * Only Fp curves implemented for now + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + (function () { + // Constructor function of Global EllipticCurve object + var ec = (window.EllipticCurve = function () {}); + + // ---------------- + // ECFieldElementFp constructor + // q instanceof BigInteger + // x instanceof BigInteger + ec.FieldElementFp = function (q, x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; + }; + + ec.FieldElementFp.prototype.equals = function (other) { + if (other == this) return true; + return this.q.equals(other.q) && this.x.equals(other.x); + }; + + ec.FieldElementFp.prototype.toBigInteger = function () { + return this.x; + }; + + ec.FieldElementFp.prototype.negate = function () { + return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); + }; + + ec.FieldElementFp.prototype.add = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.add(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.subtract = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.subtract(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.multiply = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.multiply(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.square = function () { + return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); + }; + + ec.FieldElementFp.prototype.divide = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.getByteLength = function () { + return Math.floor((this.toBigInteger().bitLength() + 7) / 8); + }; + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + * + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.prototype.sqrt = function () { + if (!this.q.testBit(0)) throw new Error("even value of q"); + + // p mod 4 == 3 + if (this.q.testBit(1)) { + // z = g^(u+1) + p, p = 4u + 3 + var z = new ec.FieldElementFp( + this.q, + this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q) + ); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + var legendreExponent = qMinusOne.shiftRight(1); + if (!this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE)) + return null; + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + var Q = this.x; + var fourQ = Q.shiftLeft(2).mod(this.q); + var U, V; + + do { + var rand = new SecureRandom(); + var P; + do { + P = new BigInteger(this.q.bitLength(), rand); + } while ( + P.compareTo(this.q) >= 0 || + !P.multiply(P) + .subtract(fourQ) + .modPow(legendreExponent, this.q) + .equals(qMinusOne) + ); + + var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); + + U = result[0]; + V = result[1]; + if (V.multiply(V).mod(this.q).equals(fourQ)) { + // Integer division by 2, mod q + if (V.testBit(0)) { + V = V.add(this.q); + } + V = V.shiftRight(1); + return new ec.FieldElementFp(this.q, V); + } + } while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; + }; + /*! + * Crypto-JS 2.5.4 BlockModes.js + * contribution from Simon Greatrix + */ + + (function (C) { + // Create pad namespace + var C_pad = (C.pad = {}); + + // Calculate the number of padding bytes required. + function _requiredPadding(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = blockSizeInBytes - (message.length % blockSizeInBytes); + return reqd; + } + + // Remove padding when the final byte gives the number of padding bytes. + var _unpadLength = function (cipher, message, alg, padding) { + var pad = message.pop(); + if (pad == 0) { + throw new Error( + "Invalid zero-length padding specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + var maxPad = cipher._blocksize * 4; + if (pad > maxPad) { + throw new Error( + "Invalid padding length of " + + pad + + " specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + for (var i = 1; i < pad; i++) { + var b = message.pop(); + if (padding != undefined && padding != b) { + throw new Error( + "Invalid padding byte of 0x" + + b.toString(16) + + " specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + } + }; + + // No-operation padding, used for stream ciphers + C_pad.NoPadding = { + pad: function (cipher, message) {}, + unpad: function (cipher, message) {}, + }; + + // Zero Padding. + // + // If the message is not an exact number of blocks, the final block is + // completed with 0x00 bytes. There is no unpadding. + C_pad.ZeroPadding = { + pad: function (cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = message.length % blockSizeInBytes; + if (reqd != 0) { + for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) { + message.push(0x00); + } + } + }, + + unpad: function (cipher, message) { + while (message[message.length - 1] == 0) { + message.pop(); + } + }, + }; + + // ISO/IEC 7816-4 padding. + // + // Pads the plain text with an 0x80 byte followed by as many 0x00 + // bytes are required to complete the block. + C_pad.iso7816 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + message.push(0x80); + for (; reqd > 1; reqd--) { + message.push(0x00); + } + }, + + unpad: function (cipher, message) { + var padLength; + for ( + padLength = cipher._blocksize * 4; + padLength > 0; + padLength-- + ) { + var b = message.pop(); + if (b == 0x80) return; + if (b != 0x00) { + throw new Error( + "ISO-7816 padding byte must be 0, not 0x" + + b.toString(16) + + ". Wrong cipher specification or key used?" + ); + } + } + throw new Error( + "ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?" + ); + }, + }; + + // ANSI X.923 padding + // + // The final block is padded with zeros except for the last byte of the + // last block which contains the number of padding bytes. + C_pad.ansix923 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(0x00); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ANSI X.923", 0); + }, + }; + + // ISO 10126 + // + // The final block is padded with random bytes except for the last + // byte of the last block which contains the number of padding bytes. + C_pad.iso10126 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(Math.floor(Math.random() * 256)); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ISO 10126", undefined); + }, + }; + + // PKCS7 padding + // + // PKCS7 is described in RFC 5652. Padding is in whole bytes. The + // value of each added byte is the number of bytes that are added, + // i.e. N bytes, each of value N are added. + C_pad.pkcs7 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 0; i < reqd; i++) { + message.push(reqd); + } + }, + + unpad: function (cipher, message) { + _unpadLength( + cipher, + message, + "PKCS 7", + message[message.length - 1] + ); + }, + }; + + // Create mode namespace + var C_mode = (C.mode = {}); + + /** + * Mode base "class". + */ + var Mode = (C_mode.Mode = function (padding) { + if (padding) { + this._padding = padding; + } + }); + + Mode.prototype = { + encrypt: function (cipher, m, iv) { + this._padding.pad(cipher, m); + this._doEncrypt(cipher, m, iv); + }, + + decrypt: function (cipher, m, iv) { + this._doDecrypt(cipher, m, iv); + this._padding.unpad(cipher, m); + }, + + // Default padding + _padding: C_pad.iso7816, + }; + + /** + * Electronic Code Book mode. + * + * ECB applies the cipher directly against each block of the input. + * + * ECB does not require an initialization vector. + */ + var ECB = (C_mode.ECB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var ECB_prototype = (ECB.prototype = new Mode()); + + // Concrete steps for Mode template + ECB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + cipher._encryptblock(m, offset); + } + }; + ECB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + cipher._decryptblock(c, offset); + } + }; + + // ECB never uses an IV + ECB_prototype.fixOptions = function (options) { + options.iv = []; + }; + + /** + * Cipher block chaining + * + * The first block is XORed with the IV. Subsequent blocks are XOR with the + * previous cipher output. + */ + var CBC = (C_mode.CBC = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CBC_prototype = (CBC.prototype = new Mode()); + + // Concrete steps for Mode template + CBC_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + if (offset == 0) { + // XOR first block using IV + for (var i = 0; i < blockSizeInBytes; i++) m[i] ^= iv[i]; + } else { + // XOR this block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) + m[offset + i] ^= m[offset + i - blockSizeInBytes]; + } + // Encrypt block + cipher._encryptblock(m, offset); + } + }; + CBC_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // At the start, the previously crypted block is the IV + var prevCryptedBlock = iv; + + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + // Save this crypted block + var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); + // Decrypt block + cipher._decryptblock(c, offset); + // XOR decrypted block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) { + c[offset + i] ^= prevCryptedBlock[i]; + } + prevCryptedBlock = thisCryptedBlock; + } + }; + + /** + * Cipher feed back + * + * The cipher output is XORed with the plain text to produce the cipher output, + * which is then fed back into the cipher to produce a bit pattern to XOR the + * next block with. + * + * This is a stream cipher mode and does not require padding. + */ + var CFB = (C_mode.CFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CFB_prototype = (CFB.prototype = new Mode()); + + // Override padding + CFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + CFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + m[i] ^= keystream[j]; + keystream[j] = m[i]; + } + }; + CFB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < c.length; i++) { + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + var b = c[i]; + c[i] ^= keystream[j]; + keystream[j] = b; + } + }; + + /** + * Output feed back + * + * The cipher repeatedly encrypts its own output. The output is XORed with the + * plain text to produce the cipher text. + * + * This is a stream cipher mode and does not require padding. + */ + var OFB = (C_mode.OFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var OFB_prototype = (OFB.prototype = new Mode()); + + // Override padding + OFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + OFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + // Generate keystream + if (i % blockSizeInBytes == 0) cipher._encryptblock(keystream, 0); + + // Encrypt byte + m[i] ^= keystream[i % blockSizeInBytes]; + } + }; + OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; + + /** + * Counter + * @author Gergely Risko + * + * After every block the last 4 bytes of the IV is increased by one + * with carry and that IV is used for the next block. + * + * This is a stream cipher mode and does not require padding. + */ + var CTR = (C_mode.CTR = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CTR_prototype = (CTR.prototype = new Mode()); + + // Override padding + CTR_prototype._padding = C_pad.NoPadding; + + CTR_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + var counter = iv.slice(0); + + for (var i = 0; i < m.length; ) { + // do not lose iv + var keystream = counter.slice(0); + + // Generate keystream for next block + cipher._encryptblock(keystream, 0); + + // XOR keystream with block + for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { + m[i] ^= keystream[j]; + } + + // Increase counter + if (++counter[blockSizeInBytes - 1] == 256) { + counter[blockSizeInBytes - 1] = 0; + if (++counter[blockSizeInBytes - 2] == 256) { + counter[blockSizeInBytes - 2] = 0; + if (++counter[blockSizeInBytes - 3] == 256) { + counter[blockSizeInBytes - 3] = 0; + ++counter[blockSizeInBytes - 4]; + } + } + } + } + }; + CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; + })(Crypto); + + /*! + * Crypto-JS v2.5.4 PBKDF2.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.PBKDF2 = function (password, salt, keylen, options) { + // Convert to byte arrays + if (password.constructor == String) + password = UTF8.stringToBytes(password); + if (salt.constructor == String) salt = UTF8.stringToBytes(salt); + /* else, assume byte arrays already */ + + // Defaults + var hasher = (options && options.hasher) || C.SHA1, + iterations = (options && options.iterations) || 1; + + // Pseudo-random function + function PRF(password, salt) { + return C.HMAC(hasher, salt, password, { + asBytes: true, + }); + } + + // Generate key + var derivedKeyBytes = [], + blockindex = 1; + while (derivedKeyBytes.length < keylen) { + var block = PRF( + password, + salt.concat(util.wordsToBytes([blockindex])) + ); + for (var u = block, i = 1; i < iterations; i++) { + u = PRF(password, u); + for (var j = 0; j < block.length; j++) block[j] ^= u[j]; + } + derivedKeyBytes = derivedKeyBytes.concat(block); + blockindex++; + } + + // Truncate excess bytes + derivedKeyBytes.length = keylen; + + return options && options.asBytes + ? derivedKeyBytes + : options && options.asString + ? Binary.bytesToString(derivedKeyBytes) + : util.bytesToHex(derivedKeyBytes); + }; + })(); + + /* + * Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + // https://github.com/cheongwy/node-scrypt-js + (function () { + var MAX_VALUE = 2147483647; + var workerUrl = null; + + //function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) + /* + * N = Cpu cost + * r = Memory cost + * p = parallelization cost + * + */ + window.Crypto_scrypt = function ( + passwd, + salt, + N, + r, + p, + dkLen, + callback + ) { + if (N == 0 || (N & (N - 1)) != 0) + throw Error("N must be > 0 and a power of 2"); + + if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large"); + if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large"); + + var PBKDF2_opts = { + iterations: 1, + hasher: Crypto.SHA256, + asBytes: true, + }; + + var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts); + + try { + var i = 0; + var worksDone = 0; + var makeWorker = function () { + if (!workerUrl) { + var code = "(" + scryptCore.toString() + ")()"; + var blob; + try { + blob = new Blob([code], { + type: "text/javascript", + }); + } catch (e) { + window.BlobBuilder = + window.BlobBuilder || + window.WebKitBlobBuilder || + window.MozBlobBuilder || + window.MSBlobBuilder; + blob = new BlobBuilder(); + blob.append(code); + blob = blob.getBlob("text/javascript"); + } + workerUrl = URL.createObjectURL(blob); + } + var worker = new Worker(workerUrl); + worker.onmessage = function (event) { + var Bi = event.data[0], + Bslice = event.data[1]; + worksDone++; + + if (i < p) { + worker.postMessage([N, r, p, B, i++]); + } + + var length = Bslice.length, + destPos = Bi * 128 * r, + srcPos = 0; + while (length--) { + B[destPos++] = Bslice[srcPos++]; + } + + if (worksDone == p) { + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + } + }; + return worker; + }; + var workers = [makeWorker(), makeWorker()]; + workers[0].postMessage([N, r, p, B, i++]); + if (p > 1) { + workers[1].postMessage([N, r, p, B, i++]); + } + } catch (e) { + window.setTimeout(function () { + scryptCore(); + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + }, 0); + } + + // using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use) + function scryptCore() { + var XY = [], + V = []; + + if (typeof B === "undefined") { + onmessage = function (event) { + var data = event.data; + var N = data[0], + r = data[1], + p = data[2], + B = data[3], + i = data[4]; + + var Bslice = []; + arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r); + smix(Bslice, 0, r, N, V, XY); + + postMessage([i, Bslice]); + }; + } else { + for (var i = 0; i < p; i++) { + smix(B, i * 128 * r, r, N, V, XY); + } + } + + function smix(B, Bi, r, N, V, XY) { + var Xi = 0; + var Yi = 128 * r; + var i; + + arraycopy32(B, Bi, XY, Xi, Yi); + + for (i = 0; i < N; i++) { + arraycopy32(XY, Xi, V, i * Yi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + for (i = 0; i < N; i++) { + var j = integerify(XY, Xi, r) & (N - 1); + blockxor(V, j * Yi, XY, Xi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + arraycopy32(XY, Xi, B, Bi, Yi); + } + + function blockmix_salsa8(BY, Bi, Yi, r) { + var X = []; + var i; + + arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64); + + for (i = 0; i < 2 * r; i++) { + blockxor(BY, i * 64, X, 0, 64); + salsa20_8(X); + arraycopy32(X, 0, BY, Yi + i * 64, 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + i * 2 * 64, BY, Bi + i * 64, 64); + } + + for (i = 0; i < r; i++) { + arraycopy32( + BY, + Yi + (i * 2 + 1) * 64, + BY, + Bi + (i + r) * 64, + 64 + ); + } + } + + function R(a, b) { + return (a << b) | (a >>> (32 - b)); + } + + function salsa20_8(B) { + var B32 = new Array(32); + var x = new Array(32); + var i; + + for (i = 0; i < 16; i++) { + B32[i] = (B[i * 4 + 0] & 0xff) << 0; + B32[i] |= (B[i * 4 + 1] & 0xff) << 8; + B32[i] |= (B[i * 4 + 2] & 0xff) << 16; + B32[i] |= (B[i * 4 + 3] & 0xff) << 24; + } + + arraycopy(B32, 0, x, 0, 16); + + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); + } + + for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]; + + for (i = 0; i < 16; i++) { + var bi = i * 4; + B[bi + 0] = (B32[i] >> 0) & 0xff; + B[bi + 1] = (B32[i] >> 8) & 0xff; + B[bi + 2] = (B32[i] >> 16) & 0xff; + B[bi + 3] = (B32[i] >> 24) & 0xff; + } + } + + function blockxor(S, Si, D, Di, len) { + var i = len >> 6; + while (i--) { + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + } + } + + function integerify(B, bi, r) { + var n; + + bi += (2 * r - 1) * 64; + + n = (B[bi + 0] & 0xff) << 0; + n |= (B[bi + 1] & 0xff) << 8; + n |= (B[bi + 2] & 0xff) << 16; + n |= (B[bi + 3] & 0xff) << 24; + + return n; + } + + function arraycopy(src, srcPos, dest, destPos, length) { + while (length--) { + dest[destPos++] = src[srcPos++]; + } + } + + function arraycopy32(src, srcPos, dest, destPos, length) { + var i = length >> 5; + while (i--) { + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + } + } + } // scryptCore + }; // window.Crypto_scrypt + })(); + + /*! + * Crypto-JS v2.5.4 AES.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8; + + // Precomputed SBOX + var SBOX = [ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, + 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, + 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, + 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, + 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, + 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, + 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, + 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, + 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, + 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, + 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, + 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, + 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, + 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, + 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, + 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, + 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, + 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, + 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, + 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, + 0x54, 0xbb, 0x16, + ]; + + // Compute inverse SBOX lookup table + for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; + + // Compute multiplication in GF(2^8) lookup tables + var MULT2 = [], + MULT3 = [], + MULT9 = [], + MULTB = [], + MULTD = [], + MULTE = []; + + function xtime(a, b) { + for (var result = 0, i = 0; i < 8; i++) { + if (b & 1) result ^= a; + var hiBitSet = a & 0x80; + a = (a << 1) & 0xff; + if (hiBitSet) a ^= 0x1b; + b >>>= 1; + } + return result; + } + + for (var i = 0; i < 256; i++) { + MULT2[i] = xtime(i, 2); + MULT3[i] = xtime(i, 3); + MULT9[i] = xtime(i, 9); + MULTB[i] = xtime(i, 0xb); + MULTD[i] = xtime(i, 0xd); + MULTE[i] = xtime(i, 0xe); + } + + // Precomputed RCon lookup + var RCON = [ + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, + ]; + + // Inner state + var state = [[], [], [], []], + keylength, + nrounds, + keyschedule; + + var AES = (C.AES = { + /** + * Public API + */ + + encrypt: function (message, password, options) { + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB(); + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var // Convert to bytes if message is a string + m = + message.constructor == String + ? UTF8.stringToBytes(message) + : message, + // Generate random IV + iv = options.iv || util.randomBytes(AES._blocksize * 4), + // Generate key + k = + password.constructor == String + ? // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true, + }) + : // else, assume byte array representing cryptographic key + password; + + // Encrypt + AES._init(k); + mode.encrypt(AES, m, iv); + + // Return ciphertext + m = options.iv ? m : iv.concat(m); + return options && options.asBytes ? m : util.bytesToBase64(m); + }, + + decrypt: function (ciphertext, password, options) { + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB(); + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var // Convert to bytes if ciphertext is a string + c = + ciphertext.constructor == String + ? util.base64ToBytes(ciphertext) + : ciphertext, + // Separate IV and message + iv = options.iv || c.splice(0, AES._blocksize * 4), + // Generate key + k = + password.constructor == String + ? // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true, + }) + : // else, assume byte array representing cryptographic key + password; + + // Decrypt + AES._init(k); + mode.decrypt(AES, c, iv); + + // Return plaintext + return options && options.asBytes ? c : UTF8.bytesToString(c); + }, + + /** + * Package private methods and properties + */ + + _blocksize: 4, + + _encryptblock: function (m, offset) { + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = m[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + for (var round = 1; round < nrounds; round++) { + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Mix columns + for (var col = 0; col < 4; col++) { + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; + state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; + state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; + state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[round * 4 + col][row]; + } + } + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + m[offset + col * 4 + row] = state[row][col]; + } + }, + + _decryptblock: function (c, offset) { + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = c[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + for (var round = 1; round < nrounds; round++) { + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= + keyschedule[(nrounds - round) * 4 + col][row]; + } + + // Inv mix columns + for (var col = 0; col < 4; col++) { + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; + state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; + state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; + state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; + } + } + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + c[offset + col * 4 + row] = state[row][col]; + } + }, + + /** + * Private methods + */ + + _init: function (k) { + keylength = k.length / 4; + nrounds = keylength + 6; + AES._keyexpansion(k); + }, + + // Generate a key schedule + _keyexpansion: function (k) { + keyschedule = []; + + for (var row = 0; row < keylength; row++) { + keyschedule[row] = [ + k[row * 4], + k[row * 4 + 1], + k[row * 4 + 2], + k[row * 4 + 3], + ]; + } + + for ( + var row = keylength; + row < AES._blocksize * (nrounds + 1); + row++ + ) { + var temp = [ + keyschedule[row - 1][0], + keyschedule[row - 1][1], + keyschedule[row - 1][2], + keyschedule[row - 1][3], + ]; + + if (row % keylength == 0) { + // Rot word + temp.push(temp.shift()); + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] ^= RCON[row / keylength]; + } else if (keylength > 6 && row % keylength == 4) { + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + } + + keyschedule[row] = [ + keyschedule[row - keylength][0] ^ temp[0], + keyschedule[row - keylength][1] ^ temp[1], + keyschedule[row - keylength][2] ^ temp[2], + keyschedule[row - keylength][3] ^ temp[3], + ]; + } + }, + }); + })(); + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) { + // TODO Research and apply "common-multiplicand multiplication here" + + var n = k.bitLength(); + var s = k.getLowestSetBit(); + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) { + Ql = Ql.multiply(Qh).mod(p); + if (k.testBit(j)) { + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vh).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); + } else { + Qh = Ql; + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + } + } + + Ql = Ql.multiply(Qh).mod(p); + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Ql = Ql.multiply(Qh).mod(p); + + for (var j = 1; j <= s; ++j) { + Uh = Uh.multiply(Vl).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + Ql = Ql.multiply(Ql).mod(p); + } + + return [Uh, Vl]; + }; + + // ---------------- + // ECPointFp constructor + ec.PointFp = function (curve, x, y, z, compressed) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if (z == null) { + this.z = BigInteger.ONE; + } else { + this.z = z; + } + this.zinv = null; + // compression flag + this.compressed = !!compressed; + }; + + ec.PointFp.prototype.getX = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.getY = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.equals = function (other) { + if (other == this) return true; + if (this.isInfinity()) return other.isInfinity(); + if (other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y + .toBigInteger() + .multiply(this.z) + .subtract(this.y.toBigInteger().multiply(other.z)) + .mod(this.curve.q); + if (!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x + .toBigInteger() + .multiply(this.z) + .subtract(this.x.toBigInteger().multiply(other.z)) + .mod(this.curve.q); + return v.equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.isInfinity = function () { + if (this.x == null && this.y == null) return true; + return ( + this.z.equals(BigInteger.ZERO) && + !this.y.toBigInteger().equals(BigInteger.ZERO) + ); + }; + + ec.PointFp.prototype.negate = function () { + return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); + }; + + ec.PointFp.prototype.add = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y + .toBigInteger() + .multiply(this.z) + .subtract(this.y.toBigInteger().multiply(b.z)) + .mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x + .toBigInteger() + .multiply(this.z) + .subtract(this.x.toBigInteger().multiply(b.z)) + .mod(this.curve.q); + + if (BigInteger.ZERO.equals(v)) { + if (BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2 + .subtract(x1v2.shiftLeft(1)) + .multiply(b.z) + .subtract(v3) + .multiply(v) + .mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2 + .multiply(THREE) + .multiply(u) + .subtract(y1.multiply(v3)) + .subtract(zu2.multiply(u)) + .multiply(b.z) + .add(u.multiply(v3)) + .mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ec.PointFp( + this.curve, + this.curve.fromBigInteger(x3), + this.curve.fromBigInteger(y3), + z3 + ); + }; + + ec.PointFp.prototype.twice = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) + return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if (!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w + .square() + .subtract(x1.shiftLeft(3).multiply(y1sqz1)) + .shiftLeft(1) + .multiply(y1z1) + .mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w + .multiply(THREE) + .multiply(x1) + .subtract(y1sqz1.shiftLeft(1)) + .shiftLeft(2) + .multiply(y1sqz1) + .subtract(w.square().multiply(w)) + .mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ec.PointFp( + this.curve, + this.curve.fromBigInteger(x3), + this.curve.fromBigInteger(y3), + z3 + ); + }; + + // Simple NAF (Non-Adjacent Form) multiplication algorithm + // TODO: modularize the multiplication algorithm + ec.PointFp.prototype.multiply = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; + }; + + // Compute this*j + x*k (simultaneous multiplication) + ec.PointFp.prototype.multiplyTwo = function (j, x, k) { + var i; + if (j.bitLength() > k.bitLength()) i = j.bitLength() - 1; + else i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while (i >= 0) { + R = R.twice(); + if (j.testBit(i)) { + if (k.testBit(i)) { + R = R.add(both); + } else { + R = R.add(this); + } + } else { + if (k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; + }; + + // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey + // patched by coretechs to support compressed public keys + ec.PointFp.prototype.getEncoded = function (compressed) { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. + var enc = ec.integerToBytes(x, len); + + // when compressed prepend byte depending if y point is even or odd + if (compressed) { + if (y.isEven()) { + enc.unshift(0x02); + } else { + enc.unshift(0x03); + } + } else { + enc.unshift(0x04); + enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point + } + return enc; + }; + + ec.PointFp.decodeFrom = function (curve, enc) { + var type = enc[0]; + var dataLen = enc.length - 1; + + // Extract x and y as byte arrays + var xBa = enc.slice(1, 1 + dataLen / 2); + var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); + + // Prepend zero byte to prevent interpretation as negative integer + xBa.unshift(0); + yBa.unshift(0); + + // Convert to BigIntegers + var x = new BigInteger(xBa); + var y = new BigInteger(yBa); + + // Return point + return new ec.PointFp( + curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y) + ); + }; + + ec.PointFp.prototype.add2D = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + if (this.x.equals(b.x)) { + if (this.y.equals(b.y)) { + // this = b, i.e. this must be doubled + return this.twice(); + } + // this = -b, i.e. the result is the point at infinity + return this.curve.getInfinity(); + } + + var x_x = b.x.subtract(this.x); + var y_y = b.y.subtract(this.y); + var gamma = y_y.divide(x_x); + + var x3 = gamma.square().subtract(this.x).subtract(b.x); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.twice2D = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) { + // if y1 == 0, then (x1, y1) == (x1, -y1) + // and hence this = -this and thus 2(x1, y1) == infinity + return this.curve.getInfinity(); + } + + var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); + var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); + var gamma = this.x + .square() + .multiply(THREE) + .add(this.curve.a) + .divide(this.y.multiply(TWO)); + + var x3 = gamma.square().subtract(this.x.multiply(TWO)); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.multiply2D = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add2D(hBit ? this : neg); + } + } + + return R; + }; + + ec.PointFp.prototype.isOnCurve = function () { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var a = this.curve.getA().toBigInteger(); + var b = this.curve.getB().toBigInteger(); + var n = this.curve.getQ(); + var lhs = y.multiply(y).mod(n); + var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); + return lhs.equals(rhs); + }; + + ec.PointFp.prototype.toString = function () { + return ( + "(" + + this.getX().toBigInteger().toString() + + "," + + this.getY().toBigInteger().toString() + + ")" + ); + }; + + /** + * Validate an elliptic curve point. + * + * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive + */ + ec.PointFp.prototype.validate = function () { + var n = this.curve.getQ(); + + // Check Q != O + if (this.isInfinity()) { + throw new Error("Point is at infinity."); + } + + // Check coordinate bounds + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + if ( + x.compareTo(BigInteger.ONE) < 0 || + x.compareTo(n.subtract(BigInteger.ONE)) > 0 + ) { + throw new Error("x coordinate out of bounds"); + } + if ( + y.compareTo(BigInteger.ONE) < 0 || + y.compareTo(n.subtract(BigInteger.ONE)) > 0 + ) { + throw new Error("y coordinate out of bounds"); + } + + // Check y^2 = x^3 + ax + b (mod n) + if (!this.isOnCurve()) { + throw new Error("Point is not on the curve."); + } + + // Check nQ = 0 (Q is a scalar multiple of G) + if (this.multiply(n).isInfinity()) { + // TODO: This check doesn't work - fix. + throw new Error("Point is not a scalar multiple of G."); + } + + return true; + }; + + // ---------------- + // ECCurveFp constructor + ec.CurveFp = function (q, a, b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ec.PointFp(this, null, null); + this.reducer = new Barrett(this.q); + }; + + ec.CurveFp.prototype.getQ = function () { + return this.q; + }; + + ec.CurveFp.prototype.getA = function () { + return this.a; + }; + + ec.CurveFp.prototype.getB = function () { + return this.b; + }; + + ec.CurveFp.prototype.equals = function (other) { + if (other == this) return true; + return ( + this.q.equals(other.q) && + this.a.equals(other.a) && + this.b.equals(other.b) + ); + }; + + ec.CurveFp.prototype.getInfinity = function () { + return this.infinity; + }; + + ec.CurveFp.prototype.fromBigInteger = function (x) { + return new ec.FieldElementFp(this.q, x); + }; + + ec.CurveFp.prototype.reduce = function (x) { + this.reducer.reduce(x); + }; + + // for now, work with hex strings because they're easier in JS + // compressed support added by bitaddress.org + ec.CurveFp.prototype.decodePointHex = function (s) { + var firstByte = parseInt(s.substr(0, 2), 16); + switch ( + firstByte // first byte + ) { + case 0: + return this.infinity; + case 2: // compressed + case 3: // compressed + var yTilde = firstByte & 1; + var xHex = s.substr(2, s.length - 2); + var X1 = new BigInteger(xHex, 16); + return this.decompressPoint(yTilde, X1); + case 4: // uncompressed + case 6: // hybrid + case 7: // hybrid + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len + 2, len); + + return new ec.PointFp( + this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16)) + ); + + default: + // unsupported + return null; + } + }; + + ec.CurveFp.prototype.encodePointHex = function (p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if (oLen % 2 != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; + }; + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + * + * Number yTilde + * BigInteger X1 + */ + ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) { + var x = this.fromBigInteger(X1); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + // if we can't find a sqrt we haven't got a point on the curve - run! + if (beta == null) throw new Error("Invalid point compression"); + var betaValue = beta.toBigInteger(); + var bit0 = betaValue.testBit(0) ? 1 : 0; + if (bit0 != yTilde) { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ec.PointFp(this, x, beta, null, true); + }; + + ec.fromHex = function (s) { + return new BigInteger(s, 16); + }; + + ec.integerToBytes = function (i, len) { + var bytes = i.toByteArrayUnsigned(); + if (len < bytes.length) { + bytes = bytes.slice(bytes.length - len); + } else + while (len > bytes.length) { + bytes.unshift(0); + } + return bytes; + }; + + // Named EC curves + // ---------------- + // X9ECParameters constructor + ec.X9Parameters = function (curve, g, n, h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + }; + ec.X9Parameters.prototype.getCurve = function () { + return this.curve; + }; + ec.X9Parameters.prototype.getG = function () { + return this.g; + }; + ec.X9Parameters.prototype.getN = function () { + return this.n; + }; + ec.X9Parameters.prototype.getH = function () { + return this.h; + }; + + // secp256k1 is the Curve used by Bitcoin + ec.secNamedCurves = { + // used by Bitcoin + secp256k1: function () { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + var p = ec.fromHex( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F" + ); + var a = BigInteger.ZERO; + var b = ec.fromHex("7"); + var n = ec.fromHex( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" + ); + var h = BigInteger.ONE; + var curve = new ec.CurveFp(p, a, b); + var G = curve.decodePointHex( + "04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" + ); + return new ec.X9Parameters(curve, G, n, h); + }, + }; + + // secp256k1 called by Bitcoin's ECKEY + ec.getSECCurveByName = function (name) { + if (ec.secNamedCurves[name] == undefined) return null; + return ec.secNamedCurves[name](); + }; + })(); + + //bitTrx.js + (function () { + var bitjs = (window.bitjs = function () {}); + + /* public vars */ + bitjs.pub = 0x23; // flochange - changed the prefix to FLO Mainnet PublicKey Prefix 0x23 + bitjs.priv = 0xa3; //flochange - changed the prefix to FLO Mainnet Private key prefix 0xa3 + bitjs.compressed = false; + + /* provide a privkey and return an WIF */ + bitjs.privkey2wif = function (h) { + var r = Crypto.util.hexToBytes(h); + + if (bitjs.compressed == true) { + r.push(0x01); + } + + r.unshift(bitjs.priv); + var hash = Crypto.SHA256( + Crypto.SHA256(r, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var checksum = hash.slice(0, 4); + + return B58.encode(r.concat(checksum)); + }; + + /* convert a wif key back to a private key */ + bitjs.wif2privkey = function (wif) { + var compressed = false; + var decode = B58.decode(wif); + var key = decode.slice(0, decode.length - 4); + key = key.slice(1, key.length); + if (key.length >= 33 && key[key.length - 1] == 0x01) { + key = key.slice(0, key.length - 1); + compressed = true; + } + return { + privkey: Crypto.util.bytesToHex(key), + compressed: compressed, + }; + }; + + /* convert a wif to a pubkey */ + bitjs.wif2pubkey = function (wif) { + var compressed = bitjs.compressed; + var r = bitjs.wif2privkey(wif); + bitjs.compressed = r["compressed"]; + var pubkey = bitjs.newPubkey(r["privkey"]); + bitjs.compressed = compressed; + return { + pubkey: pubkey, + compressed: r["compressed"], + }; + }; + + /* convert a wif to a address */ + bitjs.wif2address = function (wif) { + var r = bitjs.wif2pubkey(wif); + return { + address: bitjs.pubkey2address(r["pubkey"]), + compressed: r["compressed"], + }; + }; + + /* generate a public key from a private key */ + bitjs.newPubkey = function (hash) { + var privateKeyBigInt = BigInteger.fromByteArrayUnsigned( + Crypto.util.hexToBytes(hash) + ); + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + + var curvePt = curve.getG().multiply(privateKeyBigInt); + var x = curvePt.getX().toBigInteger(); + var y = curvePt.getY().toBigInteger(); + + var publicKeyBytes = EllipticCurve.integerToBytes(x, 32); + publicKeyBytes = publicKeyBytes.concat( + EllipticCurve.integerToBytes(y, 32) + ); + publicKeyBytes.unshift(0x04); + + if (bitjs.compressed == true) { + var publicKeyBytesCompressed = EllipticCurve.integerToBytes(x, 32); + if (y.isEven()) { + publicKeyBytesCompressed.unshift(0x02); + } else { + publicKeyBytesCompressed.unshift(0x03); + } + return Crypto.util.bytesToHex(publicKeyBytesCompressed); + } else { + return Crypto.util.bytesToHex(publicKeyBytes); + } + }; + + /* provide a public key and return address */ + bitjs.pubkey2address = function (h, byte) { + var r = ripemd160( + Crypto.SHA256(Crypto.util.hexToBytes(h), { + asBytes: true, + }) + ); + r.unshift(byte || bitjs.pub); + var hash = Crypto.SHA256( + Crypto.SHA256(r, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var checksum = hash.slice(0, 4); + return B58.encode(r.concat(checksum)); + }; + + bitjs.transaction = function () { + var btrx = {}; + btrx.version = 2; //flochange look at this version + btrx.inputs = []; + btrx.outputs = []; + btrx.locktime = 0; + btrx.floData = ""; //flochange .. look at this + + btrx.addinput = function (txid, index, scriptPubKey, sequence) { + var o = {}; + o.outpoint = { + hash: txid, + index: index, + }; + //o.script = []; Signature and Public Key should be added after singning + o.script = Crypto.util.hexToBytes(scriptPubKey); //push previous output pubkey script + o.sequence = sequence || (btrx.locktime == 0 ? 4294967295 : 0); + return this.inputs.push(o); + }; + + btrx.addoutput = function (address, value) { + var o = {}; + var buf = []; + var addrDecoded = btrx.addressDecode(address); + o.value = new BigInteger("" + Math.round(value * 1 * 1e8), 10); + buf.push(118); //OP_DUP + buf.push(169); //OP_HASH160 + buf.push(addrDecoded.length); + buf = buf.concat(addrDecoded); // address in bytes + buf.push(136); //OP_EQUALVERIFY + buf.push(172); // OP_CHECKSIG + o.script = buf; + return this.outputs.push(o); + }; + + btrx.addflodata = function (txcomments) { + // flochange - this whole function needs to be done + this.floData = txcomments; + return this.floData; //flochange .. returning the txcomments -- check if the function return will assign + }; + + // Only standard addresses + btrx.addressDecode = function (address) { + var bytes = B58.decode(address); + var front = bytes.slice(0, bytes.length - 4); + var back = bytes.slice(bytes.length - 4); + var checksum = Crypto.SHA256( + Crypto.SHA256(front, { + asBytes: true, + }), + { + asBytes: true, + } + ).slice(0, 4); + if (checksum + "" == back + "") { + return front.slice(1); + } + }; + + /* generate the transaction hash to sign from a transaction input */ + btrx.transactionHash = function (index, sigHashType) { + var clone = bitjs.clone(this); + var shType = sigHashType || 1; + + /* black out all other ins, except this one */ + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].script = []; + } + } + + if (clone.inputs && clone.inputs[index]) { + /* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG + and https://bitcoin.org/en/developer-guide#signature-hash-type */ + + if (shType == 1) { + //SIGHASH_ALL 0x01 + } else if (shType == 2) { + //SIGHASH_NONE 0x02 + clone.outputs = []; + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + } else if (shType == 3) { + //SIGHASH_SINGLE 0x03 + clone.outputs.length = index + 1; + + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + } else if (shType >= 128) { + //SIGHASH_ANYONECANPAY 0x80 + clone.inputs = [clone.inputs[index]]; + + if (shType == 129) { + // SIGHASH_ALL + SIGHASH_ANYONECANPAY + } else if (shType == 130) { + // SIGHASH_NONE + SIGHASH_ANYONECANPAY + clone.outputs = []; + } else if (shType == 131) { + // SIGHASH_SINGLE + SIGHASH_ANYONECANPAY + clone.outputs.length = index + 1; + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + } + } + + var buffer = Crypto.util.hexToBytes(clone.serialize()); + buffer = buffer.concat(bitjs.numToBytes(parseInt(shType), 4)); + var hash = Crypto.SHA256(buffer, { + asBytes: true, + }); + var r = Crypto.util.bytesToHex( + Crypto.SHA256(hash, { + asBytes: true, + }) + ); + return r; + } else { + return false; + } + }; + + /* generate a signature from a transaction hash */ + btrx.transactionSig = function (index, wif, sigHashType, txhash) { + function serializeSig(r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + } + + var shType = sigHashType || 1; + var hash = + txhash || + Crypto.util.hexToBytes(this.transactionHash(index, shType)); + + if (hash) { + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var key = bitjs.wif2privkey(wif); + var priv = BigInteger.fromByteArrayUnsigned( + Crypto.util.hexToBytes(key["privkey"]) + ); + var n = curve.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + var badrs = 0; + do { + var k = this.deterministicK(wif, hash, badrs); + var G = curve.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + var s = k + .modInverse(n) + .multiply(e.add(priv.multiply(r))) + .mod(n); + badrs++; + } while ( + r.compareTo(BigInteger.ZERO) <= 0 || + s.compareTo(BigInteger.ZERO) <= 0 + ); + + // Force lower s values per BIP62 + var halfn = n.shiftRight(1); + if (s.compareTo(halfn) > 0) { + s = n.subtract(s); + } + + var sig = serializeSig(r, s); + sig.push(parseInt(shType, 10)); + + return Crypto.util.bytesToHex(sig); + } else { + return false; + } + }; + + // https://tools.ietf.org/html/rfc6979#section-3.2 + btrx.deterministicK = function (wif, hash, badrs) { + // if r or s were invalid when this function was used in signing, + // we do not want to actually compute r, s here for efficiency, so, + // we can increment badrs. explained at end of RFC 6979 section 3.2 + + // wif is b58check encoded wif privkey. + // hash is byte array of transaction digest. + // badrs is used only if the k resulted in bad r or s. + + // some necessary things out of the way for clarity. + badrs = badrs || 0; + var key = bitjs.wif2privkey(wif); + var x = Crypto.util.hexToBytes(key["privkey"]); + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var N = curve.getN(); + + // Step: a + // hash is a byteArray of the message digest. so h1 == hash in our case + + // Step: b + var v = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + ]; + + // Step: c + var k = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + // Step: d + k = Crypto.HMAC( + Crypto.SHA256, + v.concat([0]).concat(x).concat(hash), + k, + { + asBytes: true, + } + ); + + // Step: e + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + + // Step: f + k = Crypto.HMAC( + Crypto.SHA256, + v.concat([1]).concat(x).concat(hash), + k, + { + asBytes: true, + } + ); + + // Step: g + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + + // Step: h1 + var T = []; + + // Step: h2 (since we know tlen = qlen, just copy v to T.) + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + T = v; + + // Step: h3 + var KBigInt = BigInteger.fromByteArrayUnsigned(T); + + // loop if KBigInt is not in the range of [1, N-1] or if badrs needs incrementing. + var i = 0; + while ( + KBigInt.compareTo(N) >= 0 || + KBigInt.compareTo(BigInteger.ZERO) <= 0 || + i < badrs + ) { + k = Crypto.HMAC(Crypto.SHA256, v.concat([0]), k, { + asBytes: true, + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + T = v; + KBigInt = BigInteger.fromByteArrayUnsigned(T); + i++; + } + + return KBigInt; + }; + + /* sign a "standard" input */ + btrx.signinput = function (index, wif, sigHashType) { + var key = bitjs.wif2pubkey(wif); + var shType = sigHashType || 1; + var signature = this.transactionSig(index, wif, shType); + var buf = []; + var sigBytes = Crypto.util.hexToBytes(signature); + buf.push(sigBytes.length); + buf = buf.concat(sigBytes); + var pubKeyBytes = Crypto.util.hexToBytes(key["pubkey"]); + buf.push(pubKeyBytes.length); + buf = buf.concat(pubKeyBytes); + this.inputs[index].script = buf; + return true; + }; + + /* sign inputs */ + btrx.sign = function (wif, sigHashType) { + var shType = sigHashType || 1; + for (var i = 0; i < this.inputs.length; i++) { + this.signinput(i, wif, shType); + } + return this.serialize(); + }; + + /* serialize a transaction */ + btrx.serialize = function () { + var buffer = []; + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.version), 4)); + + buffer = buffer.concat(bitjs.numToVarInt(this.inputs.length)); + for (var i = 0; i < this.inputs.length; i++) { + var txin = this.inputs[i]; + buffer = buffer.concat( + Crypto.util.hexToBytes(txin.outpoint.hash).reverse() + ); + buffer = buffer.concat( + bitjs.numToBytes(parseInt(txin.outpoint.index), 4) + ); + var scriptBytes = txin.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + buffer = buffer.concat( + bitjs.numToBytes(parseInt(txin.sequence), 4) + ); + } + buffer = buffer.concat(bitjs.numToVarInt(this.outputs.length)); + + for (var i = 0; i < this.outputs.length; i++) { + var txout = this.outputs[i]; + buffer = buffer.concat(bitjs.numToBytes(txout.value, 8)); + var scriptBytes = txout.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + } + + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.locktime), 4)); + flohex = ascii_to_hexa(this.floData); + floDataCount = this.floData.length; + + //flochange -- creating unique data character count logic for floData. This string is prefixed before actual floData string in Raw Transaction + if (floDataCount <= 16) { + floDataCountString = floDataCount.toString(16); + floDataCountString = "0" + floDataCountString; + } else if (floDataCount < 253) { + floDataCountString = floDataCount.toString(16); + } else if (floDataCount <= 1023) { + floDataCountAdjusted = floDataCount - 253 + parseInt("0xfd00fd"); + floDataCountStringAdjusted = floDataCountAdjusted.toString(16); + floDataCountString = + floDataCountStringAdjusted.substr(0, 2) + + floDataCountStringAdjusted.substr(4, 2) + + floDataCountStringAdjusted.substr(2, 2); + } else { + floDataCountString = "Character Limit Exceeded"; + } + + return Crypto.util.bytesToHex(buffer) + floDataCountString + flohex; // flochange -- Addition of floDataCountString and floData in serialization + }; + + return btrx; + }; + + bitjs.numToBytes = function (num, bytes) { + if (typeof bytes === "undefined") bytes = 8; + if (bytes == 0) { + return []; + } else if (num == -1) { + return Crypto.util.hexToBytes("ffffffffffffffff"); + } else { + return [num % 256].concat( + bitjs.numToBytes(Math.floor(num / 256), bytes - 1) + ); + } + }; + + bitjs.numToByteArray = function (num) { + if (num <= 256) { + return [num]; + } else { + return [num % 256].concat( + bitjs.numToByteArray(Math.floor(num / 256)) + ); + } + }; + + bitjs.numToVarInt = function (num) { + if (num < 253) { + return [num]; + } else if (num < 65536) { + return [253].concat(bitjs.numToBytes(num, 2)); + } else if (num < 4294967296) { + return [254].concat(bitjs.numToBytes(num, 4)); + } else { + return [255].concat(bitjs.numToBytes(num, 8)); + } + }; + + bitjs.bytesToNum = function (bytes) { + if (bytes.length == 0) return 0; + else return bytes[0] + 256 * bitjs.bytesToNum(bytes.slice(1)); + }; + + /* clone an object */ + bitjs.clone = function (obj) { + if (obj == null || typeof obj != "object") return obj; + var temp = new obj.constructor(); + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + temp[key] = bitjs.clone(obj[key]); + } + } + return temp; + }; + + var B58 = (bitjs.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function (input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(""); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function (input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add( + BigInteger.valueOf(alphaIndex).multiply( + B58.base.pow(input.length - 1 - i) + ) + ); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + }, + }); + return bitjs; + })(); + + /* + Copyright (c) 2011 Stefan Thomas + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/1a7fc9d063f864058809d06ef4542af40be3558f/src/bitcoin.js + (function (exports) { + var Bitcoin = exports; + })("object" === typeof module ? module.exports : (window.Bitcoin = {})); + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js + (function (Bitcoin) { + Bitcoin.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function (input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(""); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function (input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add( + BigInteger.valueOf(alphaIndex).multiply( + B58.base.pow(input.length - 1 - i) + ) + ); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + }, + }; + + var B58 = Bitcoin.Base58; + })("undefined" != typeof Bitcoin ? Bitcoin : module.exports); + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js + Bitcoin.Address = function (bytes) { + if (floGlobals.blockchain == "FLO") this.version = 0x23; + // FLO mainnet public address + else if (floGlobals.blockchain == "FLO_TEST") this.version = 0x73; // FLO testnet public address + if ("string" == typeof bytes) { + bytes = Bitcoin.Address.decodeString(bytes, this.version); + } + this.hash = bytes; + }; + + Bitcoin.Address.networkVersion = 0x23; // (FLO mainnet 0x23, 35D), (Bitcoin Mainnet, 0x00, 0D) // *this has no effect * + + /** + * Serialize this object as a standard Bitcoin address. + * + * Returns the address as a base58-encoded string in the standardized format. + */ + Bitcoin.Address.prototype.toString = function () { + // Get a copy of the hash + var hash = this.hash.slice(0); + + // Version + hash.unshift(this.version); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var bytes = hash.concat(checksum.slice(0, 4)); + return Bitcoin.Base58.encode(bytes); + }; + + Bitcoin.Address.prototype.getHashBase64 = function () { + return Crypto.util.bytesToBase64(this.hash); + }; + + /** + * Parse a Bitcoin address contained in a string. + */ + Bitcoin.Address.decodeString = function (string, version) { + var bytes = Bitcoin.Base58.decode(string); + var hash = bytes.slice(0, 21); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + + if ( + checksum[0] != bytes[21] || + checksum[1] != bytes[22] || + checksum[2] != bytes[23] || + checksum[3] != bytes[24] + ) { + throw "Checksum validation failed!"; + } + + if (version != hash.shift()) { + throw "Version " + hash.shift() + " not supported!"; + } + + return hash; + }; + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js + Bitcoin.ECDSA = (function () { + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + var rng = new SecureRandom(); + + var P_OVER_FOUR = null; + + function implShamirsTrick(P, k, Q, l) { + var m = Math.max(k.bitLength(), l.bitLength()); + var Z = P.add2D(Q); + var R = P.curve.getInfinity(); + + for (var i = m - 1; i >= 0; --i) { + R = R.twice2D(); + + R.z = BigInteger.ONE; + + if (k.testBit(i)) { + if (l.testBit(i)) { + R = R.add2D(Z); + } else { + R = R.add2D(P); + } + } else { + if (l.testBit(i)) { + R = R.add2D(Q); + } + } + } + + return R; + } + + var ECDSA = { + getBigRandom: function (limit) { + return new BigInteger(limit.bitLength(), rng) + .mod(limit.subtract(BigInteger.ONE)) + .add(BigInteger.ONE); + }, + sign: function (hash, priv) { + var d = priv; + var n = ecparams.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + + do { + var k = ECDSA.getBigRandom(n); + var G = ecparams.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + } while (r.compareTo(BigInteger.ZERO) <= 0); + + var s = k + .modInverse(n) + .multiply(e.add(d.multiply(r))) + .mod(n); + + return ECDSA.serializeSig(r, s); + }, + + verify: function (hash, sig, pubkey) { + var r, s; + if (Bitcoin.Util.isArray(sig)) { + var obj = ECDSA.parseSig(sig); + r = obj.r; + s = obj.s; + } else if ("object" === typeof sig && sig.r && sig.s) { + r = sig.r; + s = sig.s; + } else { + throw "Invalid value for signature"; + } + + var Q; + if (pubkey instanceof ec.PointFp) { + Q = pubkey; + } else if (Bitcoin.Util.isArray(pubkey)) { + Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey); + } else { + throw "Invalid format for pubkey value, must be byte array or ec.PointFp"; + } + var e = BigInteger.fromByteArrayUnsigned(hash); + + return ECDSA.verifyRaw(e, r, s, Q); + }, + + verifyRaw: function (e, r, s, Q) { + var n = ecparams.getN(); + var G = ecparams.getG(); + + if (r.compareTo(BigInteger.ONE) < 0 || r.compareTo(n) >= 0) + return false; + + if (s.compareTo(BigInteger.ONE) < 0 || s.compareTo(n) >= 0) + return false; + + var c = s.modInverse(n); + + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // TODO(!!!): For some reason Shamir's trick isn't working with + // signed message verification!? Probably an implementation + // error! + //var point = implShamirsTrick(G, u1, Q, u2); + var point = G.multiply(u1).add(Q.multiply(u2)); + + var v = point.getX().toBigInteger().mod(n); + + return v.equals(r); + }, + + /** + * Serialize a signature into DER format. + * + * Takes two BigIntegers representing r and s and returns a byte array. + */ + serializeSig: function (r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + }, + + /** + * Parses a byte array containing a DER-encoded signature. + * + * This function will return an object of the form: + * + * { + * r: BigInteger, + * s: BigInteger + * } + */ + parseSig: function (sig) { + var cursor; + if (sig[0] != 0x30) + throw new Error("Signature not a valid DERSequence"); + + cursor = 2; + if (sig[cursor] != 0x02) + throw new Error("First element in signature must be a DERInteger"); + var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + if (sig[cursor] != 0x02) + throw new Error("Second element in signature must be a DERInteger"); + var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + + //if (cursor != sig.length) + // throw new Error("Extra bytes in signature"); + + var r = BigInteger.fromByteArrayUnsigned(rBa); + var s = BigInteger.fromByteArrayUnsigned(sBa); + + return { + r: r, + s: s, + }; + }, + + parseSigCompact: function (sig) { + if (sig.length !== 65) { + throw "Signature has the wrong length"; + } + + // Signature is prefixed with a type byte storing three bits of + // information. + var i = sig[0] - 27; + if (i < 0 || i > 7) { + throw "Invalid signature type"; + } + + var n = ecparams.getN(); + var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n); + var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n); + + return { + r: r, + s: s, + i: i, + }; + }, + + /** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ + recoverPubKey: function (r, s, hash, i) { + // The recovery parameter i has two bits. + i = i & 3; + + // The less significant bit specifies whether the y coordinate + // of the compressed point is even or not. + var isYEven = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + var n = ecparams.getN(); + var G = ecparams.getG(); + var curve = ecparams.getCurve(); + var p = curve.getQ(); + var a = curve.getA().toBigInteger(); + var b = curve.getB().toBigInteger(); + + // We precalculate (p + 1) / 4 where p is if the field order + if (!P_OVER_FOUR) { + P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)); + } + + // 1.1 Compute x + var x = isSecondKey ? r.add(n) : r; + + // 1.3 Convert x to point + var alpha = x + .multiply(x) + .multiply(x) + .add(a.multiply(x)) + .add(b) + .mod(p); + var beta = alpha.modPow(P_OVER_FOUR, p); + + var xorOdd = beta.isEven() ? i % 2 : (i + 1) % 2; + // If beta is even, but y isn't or vice versa, then convert it, + // otherwise we're done and y == beta. + var y = (beta.isEven() ? !isYEven : isYEven) + ? beta + : p.subtract(beta); + + // 1.4 Check that nR is at infinity + var R = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y) + ); + R.validate(); + + // 1.5 Compute e from M + var e = BigInteger.fromByteArrayUnsigned(hash); + var eNeg = BigInteger.ZERO.subtract(e).mod(n); + + // 1.6 Compute Q = r^-1 (sR - eG) + var rInv = r.modInverse(n); + var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv); + + Q.validate(); + if (!ECDSA.verifyRaw(e, r, s, Q)) { + throw "Pubkey recovery unsuccessful"; + } + + var pubKey = new Bitcoin.ECKey(); + pubKey.pub = Q; + return pubKey; + }, + + /** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ + calcPubkeyRecoveryParam: function (address, r, s, hash) { + for (var i = 0; i < 4; i++) { + try { + var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i); + if (pubkey.getBitcoinAddress().toString() == address) { + return i; + } + } catch (e) {} + } + throw "Unable to find valid recovery factor"; + }, + }; + + return ECDSA; + })(); + Bitcoin.KeyPool = (function () { + var KeyPool = function () { + this.keyArray = []; + + this.push = function (item) { + if (item == null || item.priv == null) return; + var doAdd = true; + // prevent duplicates from being added to the array + for (var index in this.keyArray) { + var currentItem = this.keyArray[index]; + if ( + currentItem != null && + currentItem.priv != null && + item.getBitcoinAddress() == currentItem.getBitcoinAddress() + ) { + doAdd = false; + break; + } + } + if (doAdd) this.keyArray.push(item); + }; + + this.reset = function () { + this.keyArray = []; + }; + + this.getArray = function () { + // copy array + return this.keyArray.slice(0); + }; + + this.setArray = function (ka) { + this.keyArray = ka; + }; + + this.length = function () { + return this.keyArray.length; + }; + + this.toString = function () { + var keyPoolString = "# = " + this.length() + "\n"; + var pool = this.getArray(); + for (var index in pool) { + var item = pool[index]; + if ( + Bitcoin.Util.hasMethods(item, "getBitcoinAddress", "toString") + ) { + if (item != null) { + keyPoolString += + '"' + + item.getBitcoinAddress() + + '"' + + ', "' + + item.toString("wif") + + '"\n'; + } + } + } + + return keyPoolString; + }; + + return this; + }; + + return new KeyPool(); + })(); + + Bitcoin.Bip38Key = (function () { + var Bip38 = function (address, encryptedKey) { + this.address = address; + this.priv = encryptedKey; + }; + + Bip38.prototype.getBitcoinAddress = function () { + return this.address; + }; + + Bip38.prototype.toString = function () { + return this.priv; + }; + + return Bip38; + })(); + + //https://raw.github.com/pointbiz/bitcoinjs-lib/9b2f94a028a7bc9bed94e0722563e9ff1d8e8db8/src/eckey.js + Bitcoin.ECKey = (function () { + var ECDSA = Bitcoin.ECDSA; + var KeyPool = Bitcoin.KeyPool; + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + + var ECKey = function (input) { + if (!input) { + // Generate new key + var n = ecparams.getN(); + this.priv = ECDSA.getBigRandom(n); + } else if (input instanceof BigInteger) { + // Input is a private key value + this.priv = input; + } else if (Bitcoin.Util.isArray(input)) { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(input); + } else if ("string" == typeof input) { + var bytes = null; + try { + // This part is edited for FLO. FLO WIF are always compressed WIF. FLO WIF (private key) starts with R for mainnet and c for testnet. + if ( + (floGlobals.blockchain == "FLO" && + /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + input + )) || + (floGlobals.blockchain == "FLO_TEST" && + /^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + input + )) + ) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } + + /* + if (ECKey.isWalletImportFormat(input)) { + bytes = ECKey.decodeWalletImportFormat(input); + } else if (ECKey.isCompressedWalletImportFormat(input)) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isMiniFormat(input)) { + bytes = Crypto.SHA256(input, { asBytes: true }); + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } else if (ECKey.isBase64Format(input)) { + bytes = Crypto.util.base64ToBytes(input); + } + */ + } catch (exc1) { + this.setError(exc1); + } + + if (ECKey.isBase6Format(input)) { + this.priv = new BigInteger(input, 6); + } else if (bytes == null || bytes.length != 32) { + this.priv = null; + } else { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(bytes); + } + } + + this.compressed = + this.compressed == undefined + ? !!ECKey.compressByDefault + : this.compressed; + try { + // check not zero + if (this.priv != null && BigInteger.ZERO.compareTo(this.priv) == 0) + this.setError("Error: BigInteger equal to zero."); + // valid range [0x1, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140]) + var hexKeyRangeLimit = + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140"; + var rangeLimitBytes = Crypto.util.hexToBytes(hexKeyRangeLimit); + var limitBigInt = BigInteger.fromByteArrayUnsigned(rangeLimitBytes); + if (this.priv != null && limitBigInt.compareTo(this.priv) < 0) + this.setError("Error: BigInteger outside of curve range."); + + if (this.priv != null) { + KeyPool.push(this); + } + } catch (exc2) { + this.setError(exc2); + } + }; + + if (floGlobals.blockchain == "FLO") ECKey.privateKeyPrefix = 0xa3; + //(Bitcoin mainnet 0x80 testnet 0xEF) (FLO mainnet 0xA3 163 D) + else if (floGlobals.blockchain == "FLO_TEST") + ECKey.privateKeyPrefix = 0xef; //FLO testnet + + /** + * Whether public keys should be returned compressed by default. + */ + ECKey.compressByDefault = false; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setError = function (err) { + this.error = err; + this.priv = null; + return this; + }; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setCompressed = function (v) { + this.compressed = !!v; + if (this.pubPoint) this.pubPoint.compressed = this.compressed; + return this; + }; + + /* + * Return public key as a byte array in DER encoding + */ + ECKey.prototype.getPub = function () { + if (this.compressed) { + if (this.pubComp) return this.pubComp; + return (this.pubComp = this.getPubPoint().getEncoded(1)); + } else { + if (this.pubUncomp) return this.pubUncomp; + return (this.pubUncomp = this.getPubPoint().getEncoded(0)); + } + }; + + /** + * Return public point as ECPoint object. + */ + ECKey.prototype.getPubPoint = function () { + if (!this.pubPoint) { + this.pubPoint = ecparams.getG().multiply(this.priv); + this.pubPoint.compressed = this.compressed; + } + return this.pubPoint; + }; + + ECKey.prototype.getPubKeyHex = function () { + if (this.compressed) { + if (this.pubKeyHexComp) return this.pubKeyHexComp; + return (this.pubKeyHexComp = Crypto.util + .bytesToHex(this.getPub()) + .toString() + .toUpperCase()); + } else { + if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp; + return (this.pubKeyHexUncomp = Crypto.util + .bytesToHex(this.getPub()) + .toString() + .toUpperCase()); + } + }; + + /** + * Get the pubKeyHash for this key. + * + * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as + * a byte array. + */ + ECKey.prototype.getPubKeyHash = function () { + if (this.compressed) { + if (this.pubKeyHashComp) return this.pubKeyHashComp; + return (this.pubKeyHashComp = Bitcoin.Util.sha256ripe160( + this.getPub() + )); + } else { + if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp; + return (this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160( + this.getPub() + )); + } + }; + + ECKey.prototype.getBitcoinAddress = function () { + var hash = this.getPubKeyHash(); + var addr = new Bitcoin.Address(hash); + return addr.toString(); + }; + + /* + * Takes a public point as a hex string or byte array + */ + ECKey.prototype.setPub = function (pub) { + // byte array + if (Bitcoin.Util.isArray(pub)) { + pub = Crypto.util.bytesToHex(pub).toString().toUpperCase(); + } + var ecPoint = ecparams.getCurve().decodePointHex(pub); + this.setCompressed(ecPoint.compressed); + this.pubPoint = ecPoint; + return this; + }; + + // Sipa Private Key Wallet Import Format + ECKey.prototype.getBitcoinWalletImportFormat = function () { + var bytes = this.getBitcoinPrivateKeyByteArray(); + if (bytes == null) return ""; + bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte + if (this.compressed) bytes.push(0x01); // append 0x01 byte for compressed format + var checksum = Crypto.SHA256( + Crypto.SHA256(bytes, { + asBytes: true, + }), + { + asBytes: true, + } + ); + bytes = bytes.concat(checksum.slice(0, 4)); + var privWif = Bitcoin.Base58.encode(bytes); + return privWif; + }; + + // Private Key Hex Format + ECKey.prototype.getBitcoinHexFormat = function () { + return Crypto.util + .bytesToHex(this.getBitcoinPrivateKeyByteArray()) + .toString() + .toUpperCase(); + }; + + // Private Key Base64 Format + ECKey.prototype.getBitcoinBase64Format = function () { + return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray()); + }; + + ECKey.prototype.getBitcoinPrivateKeyByteArray = function () { + if (this.priv == null) return null; + // Get a copy of private key as a byte array + var bytes = this.priv.toByteArrayUnsigned(); + // zero pad if private key is less than 32 bytes + while (bytes.length < 32) bytes.unshift(0x00); + return bytes; + }; + + ECKey.prototype.toString = function (format) { + format = format || ""; + if ( + format.toString().toLowerCase() == "base64" || + format.toString().toLowerCase() == "b64" + ) { + return this.getBitcoinBase64Format(); + } + // Wallet Import Format + else if (format.toString().toLowerCase() == "wif") { + return this.getBitcoinWalletImportFormat(); + } else { + return this.getBitcoinHexFormat(); + } + }; + + ECKey.prototype.sign = function (hash) { + return ECDSA.sign(hash, this.priv); + }; + + ECKey.prototype.verify = function (hash, sig) { + return ECDSA.verify(hash, sig, this.getPub()); + }; + + /** + * Parse a wallet import format private key contained in a string. + */ + ECKey.decodeWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 33); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + if ( + checksum[0] != bytes[33] || + checksum[1] != bytes[34] || + checksum[2] != bytes[35] || + checksum[3] != bytes[36] + ) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + return hash; + }; + + /** + * Parse a compressed wallet import format private key contained in a string. + */ + ECKey.decodeCompressedWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 34); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + if ( + checksum[0] != bytes[34] || + checksum[1] != bytes[35] || + checksum[2] != bytes[36] || + checksum[3] != bytes[37] + ) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + hash.pop(); + return hash; + }; + + // 64 characters [0-9A-F] + ECKey.isHexFormat = function (key) { + key = key.toString(); + return /^[A-Fa-f0-9]{64}$/.test(key); + }; + + // 51 characters base58, always starts with a '5' + ECKey.isWalletImportFormat = function (key) { + key = key.toString(); + return ECKey.privateKeyPrefix == 0x80 + ? /^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test( + key + ) + : /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test( + key + ); + }; + + // 52 characters base58 + ECKey.isCompressedWalletImportFormat = function (key) { + key = key.toString(); + return ECKey.privateKeyPrefix == 0x80 + ? /^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + key + ) + : /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + key + ); + }; + + // 44 characters + ECKey.isBase64Format = function (key) { + key = key.toString(); + return /^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test( + key + ); + }; + + // 99 characters, 1=1, if using dice convert 6 to 0 + ECKey.isBase6Format = function (key) { + key = key.toString(); + return /^[012345]{99}$/.test(key); + }; + + // 22, 26 or 30 characters, always starts with an 'S' + ECKey.isMiniFormat = function (key) { + key = key.toString(); + var validChars22 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test( + key + ); + var validChars26 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test( + key + ); + var validChars30 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test( + key + ); + var testBytes = Crypto.SHA256(key + "?", { + asBytes: true, + }); + + return ( + (testBytes[0] === 0x00 || testBytes[0] === 0x01) && + (validChars22 || validChars26 || validChars30) + ); + }; + + return ECKey; + })(); + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js + // Bitcoin utility functions + Bitcoin.Util = { + /** + * Cross-browser compatibility version of Array.isArray. + */ + isArray: + Array.isArray || + function (o) { + return Object.prototype.toString.call(o) === "[object Array]"; + }, + /** + * Create an array of a certain length filled with a specific value. + */ + makeFilledArray: function (len, val) { + var array = []; + var i = 0; + while (i < len) { + array[i++] = val; + } + return array; + }, + /** + * Turn an integer into a "var_int". + * + * "var_int" is a variable length integer used by Bitcoin's binary format. + * + * Returns a byte array. + */ + numToVarInt: function (i) { + if (i < 0xfd) { + // unsigned char + return [i]; + } else if (i <= 1 << 16) { + // unsigned short (LE) + return [0xfd, i >>> 8, i & 255]; + } else if (i <= 1 << 32) { + // unsigned int (LE) + return [0xfe].concat(Crypto.util.wordsToBytes([i])); + } else { + // unsigned long long (LE) + return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i])); + } + }, + /** + * Parse a Bitcoin value byte array, returning a BigInteger. + */ + valueToBigInt: function (valueBuffer) { + if (valueBuffer instanceof BigInteger) return valueBuffer; + + // Prepend zero byte to prevent interpretation as negative integer + return BigInteger.fromByteArrayUnsigned(valueBuffer); + }, + /** + * Format a Bitcoin value as a string. + * + * Takes a BigInteger or byte-array and returns that amount of Bitcoins in a + * nice standard formatting. + * + * Examples: + * 12.3555 + * 0.1234 + * 900.99998888 + * 34.00 + */ + formatValue: function (valueBuffer) { + var value = this.valueToBigInt(valueBuffer).toString(); + var integerPart = + value.length > 8 ? value.substr(0, value.length - 8) : "0"; + var decimalPart = + value.length > 8 ? value.substr(value.length - 8) : value; + while (decimalPart.length < 8) decimalPart = "0" + decimalPart; + decimalPart = decimalPart.replace(/0*$/, ""); + while (decimalPart.length < 2) decimalPart += "0"; + return integerPart + "." + decimalPart; + }, + /** + * Parse a floating point string as a Bitcoin value. + * + * Keep in mind that parsing user input is messy. You should always display + * the parsed value back to the user to make sure we understood his input + * correctly. + */ + parseValue: function (valueString) { + // TODO: Detect other number formats (e.g. comma as decimal separator) + var valueComp = valueString.split("."); + var integralPart = valueComp[0]; + var fractionalPart = valueComp[1] || "0"; + while (fractionalPart.length < 8) fractionalPart += "0"; + fractionalPart = fractionalPart.replace(/^0+/g, ""); + var value = BigInteger.valueOf(parseInt(integralPart)); + value = value.multiply(BigInteger.valueOf(100000000)); + value = value.add(BigInteger.valueOf(parseInt(fractionalPart))); + return value; + }, + /** + * Calculate RIPEMD160(SHA256(data)). + * + * Takes an arbitrary byte array as inputs and returns the hash as a byte + * array. + */ + sha256ripe160: function (data) { + return ripemd160( + Crypto.SHA256(data, { + asBytes: true, + }), + { + asBytes: true, + } + ); + }, + // double sha256 + dsha256: function (data) { + return Crypto.SHA256( + Crypto.SHA256(data, { + asBytes: true, + }), + { + asBytes: true, + } + ); + }, + // duck typing method + hasMethods: function (obj /*, method list as strings */) { + var i = 1, + methodName; + while ((methodName = arguments[i++])) { + if (typeof obj[methodName] != "function") { + return false; + } + } + return true; + }, + }; + + (function (ellipticCurveType) { + //Defining Elliptic Encryption Object + var ellipticEncryption = (window.ellipticCurveEncryption = + function () {}); + + ellipticEncryption.rng = new SecureRandom(); + + ellipticEncryption.getCurveParameters = function (curveName) { + //Default is secp256k1 + curveName = typeof curveName !== "undefined" ? curveName : "secp256k1"; + + var c = EllipticCurve.getSECCurveByName(curveName); + var curveDetails = { + Q: "", + A: "", + B: "", + GX: "", + GY: "", + N: "", + }; + + curveDetails.Q = c.getCurve().getQ().toString(); + curveDetails.A = c.getCurve().getA().toBigInteger().toString(); + curveDetails.B = c.getCurve().getB().toBigInteger().toString(); + curveDetails.GX = c.getG().getX().toBigInteger().toString(); + curveDetails.GY = c.getG().getY().toBigInteger().toString(); + curveDetails.N = c.getN().toString(); + + return curveDetails; + }; + + ellipticEncryption.selectedCurve = + ellipticEncryption.getCurveParameters(ellipticCurveType); + + ellipticEncryption.get_curve = function () { + return new EllipticCurve.CurveFp( + new BigInteger(this.selectedCurve.Q), + new BigInteger(this.selectedCurve.A), + new BigInteger(this.selectedCurve.B) + ); + }; + + ellipticEncryption.get_G = function (curve) { + return new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(this.selectedCurve.GX)), + curve.fromBigInteger(new BigInteger(this.selectedCurve.GY)) + ); + }; + + ellipticEncryption.pick_rand = function () { + var n = new BigInteger(this.selectedCurve.N); + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(n.bitLength(), this.rng); + return r.mod(n1).add(BigInteger.ONE); + }; + + ellipticEncryption.senderRandom = function () { + var r = this.pick_rand(); + return r.toString(); + }; + + ellipticEncryption.receiverRandom = function () { + //This is receivers private key. For now we will use random. CHANGE IT LATER + var r = this.pick_rand(); + return r.toString(); + }; + + ellipticEncryption.senderPublicString = function (senderPrivateKey) { + var senderKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(senderPrivateKey); + var P = G.multiply(a); + senderKeyECData.XValuePublicString = P.getX().toBigInteger().toString(); + senderKeyECData.YValuePublicString = P.getY().toBigInteger().toString(); + + return senderKeyECData; + }; + + //In real life ellipticEncryption.receiverPublicString is the public key of the receiver. + //you don't have to run receiverRandom and the bottom function + ellipticEncryption.receiverPublicString = function (receiverPublicKey) { + var receiverKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(receiverPublicKey); + var P = G.multiply(a); + receiverKeyECData.XValuePublicString = P.getX() + .toBigInteger() + .toString(); + receiverKeyECData.YValuePublicString = P.getY() + .toBigInteger() + .toString(); + + return receiverKeyECData; + }; + + ellipticEncryption.senderSharedKeyDerivation = function ( + receiverPublicStringXValue, + receiverPublicStringYValue, + senderPrivateKey + ) { + var senderDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(receiverPublicStringXValue)), + curve.fromBigInteger(new BigInteger(receiverPublicStringYValue)) + ); + var a = new BigInteger(senderPrivateKey); + var S = P.multiply(a); + + senderDerivedKey.XValue = S.getX().toBigInteger().toString(); + senderDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return senderDerivedKey; + }; + + ellipticEncryption.receiverSharedKeyDerivation = function ( + senderPublicStringXValue, + senderPublicStringYValue, + receiverPrivateKey + ) { + var receiverDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(senderPublicStringXValue)), + curve.fromBigInteger(new BigInteger(senderPublicStringYValue)) + ); + var a = new BigInteger(receiverPrivateKey); + var S = P.multiply(a); + + receiverDerivedKey.XValue = S.getX().toBigInteger().toString(); + receiverDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return receiverDerivedKey; + }; + })("secp256k1"); + + // secrets.js - by Alexander Stetsyuk - released under MIT License + (function (exports, global) { + var defaults = { + bits: 8, // default number of bits + radix: 16, // work with HEX by default + minBits: 3, + maxBits: 20, // this permits 1,048,575 shares, though going this high is NOT recommended in JS! + + bytesPerChar: 2, + maxBytesPerChar: 6, // Math.pow(256,7) > Math.pow(2,53) + + // Primitive polynomials (in decimal form) for Galois Fields GF(2^n), for 2 <= n <= 30 + // The index of each term in the array corresponds to the n for that polynomial + // i.e. to get the polynomial for n=16, use primitivePolynomials[16] + primitivePolynomials: [ + null, + null, + 1, + 3, + 3, + 5, + 3, + 3, + 29, + 17, + 9, + 5, + 83, + 27, + 43, + 3, + 45, + 9, + 39, + 39, + 9, + 5, + 3, + 33, + 27, + 9, + 71, + 39, + 9, + 5, + 83, + ], + + // warning for insecure PRNG + warning: + "WARNING:\nA secure random number generator was not found.\nUsing Math.random(), which is NOT cryptographically strong!", + }; + + // Protected settings object + var config = {}; + + /** @expose **/ + exports.getConfig = function () { + return { + bits: config.bits, + unsafePRNG: config.unsafePRNG, + }; + }; + + function init(bits) { + if ( + bits && + (typeof bits !== "number" || + bits % 1 !== 0 || + bits < defaults.minBits || + bits > defaults.maxBits) + ) { + throw new Error( + "Number of bits must be an integer between " + + defaults.minBits + + " and " + + defaults.maxBits + + ", inclusive." + ); + } + + config.radix = defaults.radix; + config.bits = bits || defaults.bits; + config.size = Math.pow(2, config.bits); + config.max = config.size - 1; + + // Construct the exp and log tables for multiplication. + var logs = [], + exps = [], + x = 1, + primitive = defaults.primitivePolynomials[config.bits]; + for (var i = 0; i < config.size; i++) { + exps[i] = x; + logs[x] = i; + x <<= 1; + if (x >= config.size) { + x ^= primitive; + x &= config.max; + } + } + + config.logs = logs; + config.exps = exps; + } + + /** @expose **/ + exports.init = init; + + function isInited() { + if ( + !config.bits || + !config.size || + !config.max || + !config.logs || + !config.exps || + config.logs.length !== config.size || + config.exps.length !== config.size + ) { + return false; + } + return true; + } + + // Returns a pseudo-random number generator of the form function(bits){} + // which should output a random string of 1's and 0's of length `bits` + function getRNG() { + var randomBits, crypto; + + function construct(bits, arr, radix, size) { + var str = "", + i = 0, + len = arr.length - 1; + while (i < len || str.length < bits) { + str += padLeft(parseInt(arr[i], radix).toString(2), size); + i++; + } + str = str.substr(-bits); + if ((str.match(/0/g) || []).length === str.length) { + // all zeros? + return null; + } else { + return str; + } + } + + // node.js crypto.randomBytes() + if ( + typeof require === "function" && + (crypto = require("crypto")) && + (randomBits = crypto["randomBytes"]) + ) { + return function (bits) { + var bytes = Math.ceil(bits / 8), + str = null; + + while (str === null) { + str = construct(bits, randomBits(bytes).toString("hex"), 16, 4); + } + return str; + }; + } + + // browsers with window.crypto.getRandomValues() + if ( + global["crypto"] && + typeof global["crypto"]["getRandomValues"] === "function" && + typeof global["Uint32Array"] === "function" + ) { + crypto = global["crypto"]; + return function (bits) { + var elems = Math.ceil(bits / 32), + str = null, + arr = new global["Uint32Array"](elems); + + while (str === null) { + crypto["getRandomValues"](arr); + str = construct(bits, arr, 10, 32); + } + + return str; + }; + } + + // A totally insecure RNG!!! (except in Safari) + // Will produce a warning every time it is called. + config.unsafePRNG = true; + warn(); + + var bitsPerNum = 32; + var max = Math.pow(2, bitsPerNum) - 1; + return function (bits) { + var elems = Math.ceil(bits / bitsPerNum); + var arr = [], + str = null; + while (str === null) { + for (var i = 0; i < elems; i++) { + arr[i] = Math.floor(Math.random() * max + 1); + } + str = construct(bits, arr, 10, bitsPerNum); + } + return str; + }; + } + + // Warn about using insecure rng. + // Called when Math.random() is being used. + function warn() { + global["console"]["warn"](defaults.warning); + if (typeof global["alert"] === "function" && config.alert) { + global["alert"](defaults.warning); + } + } + + // Set the PRNG to use. If no RNG function is supplied, pick a default using getRNG() + /** @expose **/ + exports.setRNG = function (rng, alert) { + if (!isInited()) { + this.init(); + } + config.unsafePRNG = false; + rng = rng || getRNG(); + + // test the RNG (5 times) + if ( + typeof rng !== "function" || + typeof rng(config.bits) !== "string" || + !parseInt(rng(config.bits), 2) || + rng(config.bits).length > config.bits || + rng(config.bits).length < config.bits + ) { + throw new Error( + "Random number generator is invalid. Supply an RNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's." + ); + } else { + config.rng = rng; + } + config.alert = !!alert; + + return !!config.unsafePRNG; + }; + + function isSetRNG() { + return typeof config.rng === "function"; + } + + // Generates a random bits-length number string using the PRNG + /** @expose **/ + exports.random = function (bits) { + if (!isSetRNG()) { + this.setRNG(); + } + + if (typeof bits !== "number" || bits % 1 !== 0 || bits < 2) { + throw new Error("Number of bits must be an integer greater than 1."); + } + + if (config.unsafePRNG) { + warn(); + } + return bin2hex(config.rng(bits)); + }; + + // Divides a `secret` number String str expressed in radix `inputRadix` (optional, default 16) + // into `numShares` shares, each expressed in radix `outputRadix` (optional, default to `inputRadix`), + // requiring `threshold` number of shares to reconstruct the secret. + // Optionally, zero-pads the secret to a length that is a multiple of padLength before sharing. + /** @expose **/ + exports.share = function ( + secret, + numShares, + threshold, + padLength, + withoutPrefix + ) { + if (!isInited()) { + this.init(); + } + if (!isSetRNG()) { + this.setRNG(); + } + + padLength = padLength || 0; + + if (typeof secret !== "string") { + throw new Error("Secret must be a string."); + } + if ( + typeof numShares !== "number" || + numShares % 1 !== 0 || + numShares < 2 + ) { + throw new Error( + "Number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive." + ); + } + if (numShares > config.max) { + var neededBits = Math.ceil(Math.log(numShares + 1) / Math.LN2); + throw new Error( + "Number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive. To create " + + numShares + + " shares, use at least " + + neededBits + + " bits." + ); + } + if ( + typeof threshold !== "number" || + threshold % 1 !== 0 || + threshold < 2 + ) { + throw new Error( + "Threshold number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive." + ); + } + if (threshold > config.max) { + var neededBits = Math.ceil(Math.log(threshold + 1) / Math.LN2); + throw new Error( + "Threshold number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive. To use a threshold of " + + threshold + + ", use at least " + + neededBits + + " bits." + ); + } + if (typeof padLength !== "number" || padLength % 1 !== 0) { + throw new Error("Zero-pad length must be an integer greater than 1."); + } + + if (config.unsafePRNG) { + warn(); + } + + secret = "1" + hex2bin(secret); // append a 1 so that we can preserve the correct number of leading zeros in our secret + secret = split(secret, padLength); + var x = new Array(numShares), + y = new Array(numShares); + for (var i = 0, len = secret.length; i < len; i++) { + var subShares = this._getShares(secret[i], numShares, threshold); + for (var j = 0; j < numShares; j++) { + x[j] = x[j] || subShares[j].x.toString(config.radix); + y[j] = padLeft(subShares[j].y.toString(2)) + (y[j] ? y[j] : ""); + } + } + var padding = config.max.toString(config.radix).length; + if (withoutPrefix) { + for (var i = 0; i < numShares; i++) { + x[i] = bin2hex(y[i]); + } + } else { + for (var i = 0; i < numShares; i++) { + x[i] = + config.bits.toString(36).toUpperCase() + + padLeft(x[i], padding) + + bin2hex(y[i]); + } + } + + return x; + }; + + // This is the basic polynomial generation and evaluation function + // for a `config.bits`-length secret (NOT an arbitrary length) + // Note: no error-checking at this stage! If `secrets` is NOT + // a NUMBER less than 2^bits-1, the output will be incorrect! + /** @expose **/ + exports._getShares = function (secret, numShares, threshold) { + var shares = []; + var coeffs = [secret]; + + for (var i = 1; i < threshold; i++) { + coeffs[i] = parseInt(config.rng(config.bits), 2); + } + for (var i = 1, len = numShares + 1; i < len; i++) { + shares[i - 1] = { + x: i, + y: horner(i, coeffs), + }; + } + return shares; + }; + + // Polynomial evaluation at `x` using Horner's Method + // TODO: this can possibly be sped up using other methods + // NOTE: fx=fx * x + coeff[i] -> exp(log(fx) + log(x)) + coeff[i], + // so if fx===0, just set fx to coeff[i] because + // using the exp/log form will result in incorrect value + function horner(x, coeffs) { + var logx = config.logs[x]; + var fx = 0; + for (var i = coeffs.length - 1; i >= 0; i--) { + if (fx === 0) { + fx = coeffs[i]; + continue; + } + fx = config.exps[(logx + config.logs[fx]) % config.max] ^ coeffs[i]; + } + return fx; + } + + function inArray(arr, val) { + for (var i = 0, len = arr.length; i < len; i++) { + if (arr[i] === val) { + return true; + } + } + return false; + } + + function processShare(share) { + var bits = parseInt(share[0], 36); + if ( + bits && + (typeof bits !== "number" || + bits % 1 !== 0 || + bits < defaults.minBits || + bits > defaults.maxBits) + ) { + throw new Error( + "Number of bits must be an integer between " + + defaults.minBits + + " and " + + defaults.maxBits + + ", inclusive." + ); + } + + var max = Math.pow(2, bits) - 1; + var idLength = max.toString(config.radix).length; + + var id = parseInt(share.substr(1, idLength), config.radix); + if (typeof id !== "number" || id % 1 !== 0 || id < 1 || id > max) { + throw new Error( + "Share id must be an integer between 1 and " + + config.max + + ", inclusive." + ); + } + share = share.substr(idLength + 1); + if (!share.length) { + throw new Error("Invalid share: zero-length share."); + } + return { + bits: bits, + id: id, + value: share, + }; + } + + /** @expose **/ + exports._processShare = processShare; + + // Protected method that evaluates the Lagrange interpolation + // polynomial at x=`at` for individual config.bits-length + // segments of each share in the `shares` Array. + // Each share is expressed in base `inputRadix`. The output + // is expressed in base `outputRadix' + function combine(at, shares) { + var setBits, + share, + x = [], + y = [], + result = "", + idx; + + for (var i = 0, len = shares.length; i < len; i++) { + share = processShare(shares[i]); + if (typeof setBits === "undefined") { + setBits = share["bits"]; + } else if (share["bits"] !== setBits) { + throw new Error("Mismatched shares: Different bit settings."); + } + + if (config.bits !== setBits) { + init(setBits); + } + + if (inArray(x, share["id"])) { + // repeated x value? + continue; + } + + idx = x.push(share["id"]) - 1; + share = split(hex2bin(share["value"])); + for (var j = 0, len2 = share.length; j < len2; j++) { + y[j] = y[j] || []; + y[j][idx] = share[j]; + } + } + + for (var i = 0, len = y.length; i < len; i++) { + result = padLeft(lagrange(at, x, y[i]).toString(2)) + result; + } + + if (at === 0) { + // reconstructing the secret + var idx = result.indexOf("1"); //find the first 1 + return bin2hex(result.slice(idx + 1)); + } else { + // generating a new share + return bin2hex(result); + } + } + + // Combine `shares` Array into the original secret + /** @expose **/ + exports.combine = function (shares) { + return combine(0, shares); + }; + + // Generate a new share with id `id` (a number between 1 and 2^bits-1) + // `id` can be a Number or a String in the default radix (16) + /** @expose **/ + exports.newShare = function (id, shares) { + if (typeof id === "string") { + id = parseInt(id, config.radix); + } + + var share = processShare(shares[0]); + var max = Math.pow(2, share["bits"]) - 1; + + if (typeof id !== "number" || id % 1 !== 0 || id < 1 || id > max) { + throw new Error( + "Share id must be an integer between 1 and " + + config.max + + ", inclusive." + ); + } + + var padding = max.toString(config.radix).length; + return ( + config.bits.toString(36).toUpperCase() + + padLeft(id.toString(config.radix), padding) + + combine(id, shares) + ); + }; + + // Evaluate the Lagrange interpolation polynomial at x = `at` + // using x and y Arrays that are of the same length, with + // corresponding elements constituting points on the polynomial. + function lagrange(at, x, y) { + var sum = 0, + product, + i, + j; + + for (var i = 0, len = x.length; i < len; i++) { + if (!y[i]) { + continue; + } + + product = config.logs[y[i]]; + for (var j = 0; j < len; j++) { + if (i === j) { + continue; + } + if (at === x[j]) { + // happens when computing a share that is in the list of shares used to compute it + product = -1; // fix for a zero product term, after which the sum should be sum^0 = sum, not sum^1 + break; + } + product = + (product + + config.logs[at ^ x[j]] - + config.logs[x[i] ^ x[j]] + + config.max) /* to make sure it's not negative */ % + config.max; + } + + sum = product === -1 ? sum : sum ^ config.exps[product]; // though exps[-1]= undefined and undefined ^ anything = anything in chrome, this behavior may not hold everywhere, so do the check + } + return sum; + } + + /** @expose **/ + exports._lagrange = lagrange; + + // Splits a number string `bits`-length segments, after first + // optionally zero-padding it to a length that is a multiple of `padLength. + // Returns array of integers (each less than 2^bits-1), with each element + // representing a `bits`-length segment of the input string from right to left, + // i.e. parts[0] represents the right-most `bits`-length segment of the input string. + function split(str, padLength) { + if (padLength) { + str = padLeft(str, padLength); + } + var parts = []; + for (var i = str.length; i > config.bits; i -= config.bits) { + parts.push(parseInt(str.slice(i - config.bits, i), 2)); + } + parts.push(parseInt(str.slice(0, i), 2)); + return parts; + } + + // Pads a string `str` with zeros on the left so that its length is a multiple of `bits` + function padLeft(str, bits) { + bits = bits || config.bits; + var missing = str.length % bits; + return (missing ? new Array(bits - missing + 1).join("0") : "") + str; + } + + function hex2bin(str) { + var bin = "", + num; + for (var i = str.length - 1; i >= 0; i--) { + num = parseInt(str[i], 16); + if (isNaN(num)) { + throw new Error("Invalid hex character."); + } + bin = padLeft(num.toString(2), 4) + bin; + } + return bin; + } + + function bin2hex(str) { + var hex = "", + num; + str = padLeft(str, 4); + for (var i = str.length; i >= 4; i -= 4) { + num = parseInt(str.slice(i - 4, i), 2); + if (isNaN(num)) { + throw new Error("Invalid binary character."); + } + hex = num.toString(16) + hex; + } + return hex; + } + + // Converts a given UTF16 character string to the HEX representation. + // Each character of the input string is represented by + // `bytesPerChar` bytes in the output string. + /** @expose **/ + exports.str2hex = function (str, bytesPerChar) { + if (typeof str !== "string") { + throw new Error("Input must be a character string."); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if ( + typeof bytesPerChar !== "number" || + bytesPerChar % 1 !== 0 || + bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar + ) { + throw new Error( + "Bytes per character must be an integer between 1 and " + + defaults.maxBytesPerChar + + ", inclusive." + ); + } + + var hexChars = 2 * bytesPerChar; + var max = Math.pow(16, hexChars) - 1; + var out = "", + num; + for (var i = 0, len = str.length; i < len; i++) { + num = str[i].charCodeAt(); + if (isNaN(num)) { + throw new Error("Invalid character: " + str[i]); + } else if (num > max) { + var neededBytes = Math.ceil(Math.log(num + 1) / Math.log(256)); + throw new Error( + "Invalid character code (" + + num + + "). Maximum allowable is 256^bytes-1 (" + + max + + "). To convert this character, use at least " + + neededBytes + + " bytes." + ); + } else { + out = padLeft(num.toString(16), hexChars) + out; + } + } + return out; + }; + + // Converts a given HEX number string to a UTF16 character string. + /** @expose **/ + exports.hex2str = function (str, bytesPerChar) { + if (typeof str !== "string") { + throw new Error("Input must be a hexadecimal string."); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if ( + typeof bytesPerChar !== "number" || + bytesPerChar % 1 !== 0 || + bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar + ) { + throw new Error( + "Bytes per character must be an integer between 1 and " + + defaults.maxBytesPerChar + + ", inclusive." + ); + } + + var hexChars = 2 * bytesPerChar; + var out = ""; + str = padLeft(str, hexChars); + for (var i = 0, len = str.length; i < len; i += hexChars) { + out = + String.fromCharCode(parseInt(str.slice(i, i + hexChars), 16)) + out; + } + return out; + }; + + // by default, initialize without an RNG + exports.init(); + })( + typeof module !== "undefined" && module["exports"] + ? module["exports"] + : (window["shamirSecretShare"] = {}), + typeof global !== "undefined" ? global : window + ); + + //For diff base + /* + Functions available: + diff(originalObj, updatedObj) returns the difference of the original and updated objects + addedDiff(original, updatedObj) returns only the values added to the updated object + deletedDiff(original, updatedObj) returns only the values deleted in the updated object + updatedDiff(original, updatedObj) returns only the values that have been changed in the updated object + findDifference(original, updatedObj) returns an object with the added, deleted and updated differences + mergeRecurcive(original, diff) this will get you a new object that will merge all the changes between the old object and the new object + */ + (function () { + const isDate = (d) => d instanceof Date; + const isEmpty = (o) => Object.keys(o).length === 0; + const isObject = (o) => o != null && typeof o === "object"; + const properObject = (o) => + isObject(o) && !o.hasOwnProperty + ? { + ...o, + } + : o; + + const getLargerArray = (l, r) => (l.length > r.length ? l : r); + + const preserve = (diff, left, right) => { + if (!isObject(diff)) return diff; + + return Object.keys(diff).reduce((acc, key) => { + const leftArray = left[key]; + const rightArray = right[key]; + + if (Array.isArray(leftArray) && Array.isArray(rightArray)) { + const array = [...getLargerArray(leftArray, rightArray)]; + return { + ...acc, + [key]: array.reduce((acc2, item, index) => { + if (diff[key].hasOwnProperty(index)) { + acc2[index] = preserve( + diff[key][index], + leftArray[index], + rightArray[index] + ); // diff recurse and check for nested arrays + return acc2; + } + + delete acc2[index]; // no diff aka empty + return acc2; + }, array), + }; + } + + return { + ...acc, + [key]: diff[key], + }; + }, {}); + }; + + const updatedDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; + + if (!isObject(lhs) || !isObject(rhs)) return rhs; + + const l = properObject(lhs); + const r = properObject(rhs); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = updatedDiff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return acc; + }, {}); + }; + + const diff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + + const l = properObject(lhs); + const r = properObject(rhs); + + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) + ? acc + : { + ...acc, + [key]: null, + }; + }, {}); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) + return { + ...acc, + [key]: r[key], + }; // return added r key + + const difference = diff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; // return no diff + + return { + ...acc, + [key]: difference, + }; // return updated key + }, deletedValues); + }; + + const addedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + + const l = properObject(lhs); + const r = properObject(rhs); + + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = addedDiff(l[key], r[key]); + + if (isObject(difference) && isEmpty(difference)) return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return { + ...acc, + [key]: r[key], + }; + }, {}); + }; + + const arrayDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + + const l = properObject(lhs); + const r = properObject(rhs); + + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) + ? acc + : { + ...acc, + [key]: null, + }; + }, {}); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + if (Array.isArray(r) && Array.isArray(l)) { + const deletedValues = l.reduce((acc, item, index) => { + return r.hasOwnProperty(index) + ? acc.concat(item) + : acc.concat(null); + }, []); + + return r.reduce((acc, rightItem, index) => { + if (!deletedValues.hasOwnProperty(index)) { + return acc.concat(rightItem); + } + + const leftItem = l[index]; + const difference = diff(rightItem, leftItem); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) { + delete acc[index]; + return acc; // return no diff + } + + return acc + .slice(0, index) + .concat(rightItem) + .concat(acc.slice(index + 1)); // return updated key + }, deletedValues); + } + + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) + return { + ...acc, + [key]: r[key], + }; // return added r key + + const difference = diff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; // return no diff + + return { + ...acc, + [key]: difference, + }; // return updated key + }, deletedValues); + }; + + const deletedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + + const l = properObject(lhs); + const r = properObject(rhs); + + return Object.keys(l).reduce((acc, key) => { + if (r.hasOwnProperty(key)) { + const difference = deletedDiff(l[key], r[key]); + + if (isObject(difference) && isEmpty(difference)) return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return { + ...acc, + [key]: null, + }; + }, {}); + }; + + window.findDifference = (lhs, rhs) => ({ + added: addedDiff(lhs, rhs), + deleted: deletedDiff(lhs, rhs), + updated: updatedDiff(lhs, rhs), + }); + + const mergeRecursive = (obj1, obj2) => { + for (var p in obj2) { + try { + if (obj2[p].constructor == Object) { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } + // Property in destination object set; update its value. + else if (Ext.isArray(obj2[p])) { + // obj1[p] = []; + if (obj2[p].length < 1) { + obj1[p] = obj2[p]; + } else { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } + } else { + obj1[p] = obj2[p]; + } + } catch (e) { + // Property in destination object not set; create it and set its value. + obj1[p] = obj2[p]; + } + } + return obj1; + }; + + /* + var test = { + foo : { + bar : { + baz : null + } + }, + bar : 1 + }; + cleanse(test); + + Rohit: Added a small fix for object being entered as Array*/ + + const cleanse = (obj) => { + Object.keys(obj).forEach((key) => { + var value = obj[key]; + if (typeof value === "object" && value !== null) { + // Recurse... + cleanse(value); + // ...and remove if now "empty" (NOTE: insert your definition of "empty" here) + if (!Object.keys(value).length) { + delete obj[key]; + } + } else if (value === null) { + // null, remove it + delete obj[key]; + } + }); + + if (obj.constructor.toString().indexOf("Array") != -1) { + obj = obj.filter(function (el) { + return el != null; + }); + } + + return obj; + }; + + /*obj is original object or array, diff is the output of findDifference */ + window.mergeDifference = (obj, diff) => { + if (Object.keys(diff.updated).length !== 0) + obj = mergeRecursive(obj, diff.updated); + if (Object.keys(diff.deleted).length !== 0) { + obj = mergeRecursive(obj, diff.deleted); + obj = cleanse(obj); + } + if (Object.keys(diff.added).length !== 0) + obj = mergeRecursive(obj, diff.added); + return obj; + }; + })(); + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/REGENERATING INTO SUSTAINABILITY.html b/REGENERATING INTO SUSTAINABILITY.html index 2d6f564..39818c0 100644 --- a/REGENERATING INTO SUSTAINABILITY.html +++ b/REGENERATING INTO SUSTAINABILITY.html @@ -314,12 +314,7 @@
Conventional, Contemporary, Regenerative

Sustenance has always been a prerequisite to all human activities and endeavors. However, what defines the act and value of being sustained has been changing in accordance with the dynamics of social orders, human interaction, and developmental structures. Nothing is static and everything is governed by a life cycle, this can be both- an advantage and a disadvantage in ensuring well-being for our present and future generations. Industrial Revolution and population explosion have led to increasing choices for exploiting by the beneficiaries of insatiability; calling in solutions to mitigate the imbalance caused by these choices being presented as the destruction of natural resources, growing disparity, and social divides. One of the foremost efforts in highlighting this need to mitigate these unsustainable effects and finding solutions in understanding development beyond economic and infrastructural progress came with conventional sustainability. Addressing the fact that humans exploit environmental resources that are depleting and can not eventually be replaced, also in the course of their developmental action create pollutants in the environment depreciating human quality of life- conventional sustainability aims to meet current and future human needs within the confines of the environment. In 1983, the United Nations intervened to solve problems related to the global environment and its people by applying conventional sustainability parameters while analyzing the needs and conditions necessary to deal with more rapidly appearing digressions of development. The approach however fell short and static with primarily aiming at continuous economic development in a context of finite resources. The UN initiated Brundtland Commission to address the environmental, economic, and social challenges of the world. In 1987, the Commission published a report, 'Our Common Future' popularizing the concept of Sustainable Development. The UN further published an action plan called Agenda 21, for countries to execute sustainable development at the local and national levels. The goals included efficiency, human well-being, reduction of environmental damage, economic growth, and the development and implementation of technological advancements. The acceleration of global issues like deforestation, climate change, hunger, diseases, financial crises, inequality, etc., became a clear indicator of the failure of Agenda 21 by the late 90s.  Contemporary sustainability tried to bridge the gaps conventional couldn't by enhancing the viability of ecosystems, social justice, socio-ecological technical systems, livelihoods, and regulations. The UN revised the terms of global cooperation in 2000 by introducing the Millennium Development Goals (MDG) that aimed at reducing poverty and human deprivation at unmatched scales in collaboration with several countries. The MDGs made gradual progress on each of its eight goals and its targets to be met by 2015, but were widely criticized for being mechanical and neglecting some major social issues important to sustaining collective well-being. The UN then consulted all member countries and conducted several public surveys to understand the needs of people, and the result was the draft made on Sustainable Development Goals that were introduced in 2015 with the aim to create a better and sustainable future for all. The SDGs consist of 17 goals and 169 targets drafted by an open working group that worked with global organizations and countries. Over 193 countries of the UN assembly have vowed to achieve these goals by 2030. The advancing world has brought new global challenges like information warfare, surveillance, populism, technology-based inequality, and immigration; making the differences and similarities of a contracting world appear stronger, but at the same time becoming indifferent to some native and ingenious needs and skills important to fulfilling Global Goals effectively. Is the present approach to SDGs compatible enough to cooperate with these growing needs, or is the future now dependent on widely adopting a regenerative approach towards development where we can put the essence of life at the center of every decision? A hypothesis cannot be referenced for a conclusion unless there is an experiential interaction. The common economic systems are extracting life from the earth, however, the earth system in itself is a self-funded bank with all checks and clearances dependent on human motivation to nurture and respect what they have. Regenerative sustainability is much more than bringing the earth back to life as it also brings humans back to life by giving their lives more meaning.

Holistic Development

Holistic development is dependent on internal and external conditions that can sustain collective progress. 'Collective progress' can be understood as an eco-system thriving on regenerative actions and results, also differentiated as 'inner and outer sustainability.' This differentiation, however, can also be seen as an impediment to meeting sustainable development. Internal sustainability is understood with a personal and cultural reference, while external or outer sustainability is dependent on the overt conditions and limitations based on social, political, and geographical constructs. Regenerative practices are sourced in the unlimited potential within a human system, and its ability to create, sustain and improve the conditions prevalent without harming the progressive potential of the underlying fabric and framework of the system itself. A productive and sustainable system is seen as human with higher emotional intelligence and is governed by refining consciousness. Regenerative action and thought is not just sustainable, but transformational and therefore can create more out of less, and simplify for quality rather than compromise on the long-term effects for quantification. The deeper layers of understanding devoted to skill management, resource support, spiritual and cultural referencing in individual and social organization, and the network and interaction of these elements in each human system, drives its chemistry and physics to a more evolved state of sustenance, more consistently appreciating than depreciating.

-
Sustainability-related planning

Sustainable development is widely viewed as humanity's greatest learning challenge. Unsustainable lifestyles, as well as economic models and industrial systems that exacerbate environmental problems, are so deeply embedded in our society and daily lives that changing them seems nearly impossible. Nonetheless, this shift is the only option to ensure our continued survival on this planet. The UN Sustainable Development Goals (SDGs) and targets are based on the Modernity worldview, which is defined by science-driven standardization, formalization, and rationalization processes, as well as emancipatory and planning principles. The SDGs present ambitions for future action and areas such as ethics. Thus, the interpretation of the goals and targets in the SDGs can be enriched to identify and incorporate broader sets of values and beliefs about what 'the good life' is about. Reflecting on diverse worldviews about SDGs and their viewpoints on development and quality of life would be valuable and enlightening to select, define, and convey goals in a way that honors and incorporates as many worldviews, stakeholders, and perspectives as feasible. The SDGs can truly help the world's efforts to accelerate global progress toward more sustainable and life-enhancing forms of aid, ecological, social, and cultural—for everyone when such a system is undertaken with utmost care and inclusivity. The SDGs have made only modest progress overall. According to the United Nations, many people are living healthier lives now than they were at the turn of the millennium, demonstrating one area where the MDGs and SDGs have made progress. According to the UN, 80 percent of live births in the globe were assisted by a qualified health professional between 2012 and 2017, up from 62 percent between 2000 and 2005. While some progress has been made, attendees at sustainable development events complain that the SDGs are not being implemented at the rate or with the momentum required to fulfill the 2030 deadline. The more sustainable tools, such as organic farming or renewable energy sources have a host of drawbacks that need to be tackled intelligently to help sustainability. Industries that are more responsible for affecting the environment would have more requirements to correctly function the treatment of their waste. Changes to preserve and care for biodiversity and ecosystems can cause several industries to reduce their activities that can bring unemployment in many areas. There are sustainable limits for material and energy use. Climate change, global warming, forest fires are evidently displaying the degenerating condition of this world. The adverse effect on biodiversity can also be seen with the loss of fishes, species, pollinators, acidification of oceans, and loss of life on earth as a whole. If the natural system is manipulated by an external force, you have to face the repercussions. Therefore, these problems are not related to science, rather it's a human problem. It is a system crisis that can be healed by connecting more of it to itself. It is important to create a lasting change that the world environment needs. Regenerative development can help to enhance our lives and restore the living environment. It challenges people to live with living systems like nature does with itself. People are aware of the power of climate change but they are not aware of the power of human change. Regenerative development creates a vision for the present life that brings more joy and purpose to you by putting life at the center of living. The sustainable rate of usage of renewable resources can be no greater than the rate of regeneration of its source. Whereas, for a non-renewable resource like high-grade mineral ores, fossils - the sustainable rate of use can be no greater than the rate at which a renewable resource is used sustainably.

- - Vote - - -
+
Sustainability-related planning

Sustainable development is widely viewed as humanity's greatest learning challenge. Unsustainable lifestyles, as well as economic models and industrial systems that exacerbate environmental problems, are so deeply embedded in our society and daily lives that changing them seems nearly impossible. Nonetheless, this shift is the only option to ensure our continued survival on this planet. The UN Sustainable Development Goals (SDGs) and targets are based on the Modernity worldview, which is defined by science-driven standardization, formalization, and rationalization processes, as well as emancipatory and planning principles. The SDGs present ambitions for future action and areas such as ethics. Thus, the interpretation of the goals and targets in the SDGs can be enriched to identify and incorporate broader sets of values and beliefs about what 'the good life' is about. Reflecting on diverse worldviews about SDGs and their viewpoints on development and quality of life would be valuable and enlightening to select, define, and convey goals in a way that honors and incorporates as many worldviews, stakeholders, and perspectives as feasible. The SDGs can truly help the world's efforts to accelerate global progress toward more sustainable and life-enhancing forms of aid, ecological, social, and cultural—for everyone when such a system is undertaken with utmost care and inclusivity. The SDGs have made only modest progress overall. According to the United Nations, many people are living healthier lives now than they were at the turn of the millennium, demonstrating one area where the MDGs and SDGs have made progress. According to the UN, 80 percent of live births in the globe were assisted by a qualified health professional between 2012 and 2017, up from 62 percent between 2000 and 2005. While some progress has been made, attendees at sustainable development events complain that the SDGs are not being implemented at the rate or with the momentum required to fulfill the 2030 deadline. The more sustainable tools, such as organic farming or renewable energy sources have a host of drawbacks that need to be tackled intelligently to help sustainability. Industries that are more responsible for affecting the environment would have more requirements to correctly function the treatment of their waste. Changes to preserve and care for biodiversity and ecosystems can cause several industries to reduce their activities that can bring unemployment in many areas. There are sustainable limits for material and energy use. Climate change, global warming, forest fires are evidently displaying the degenerating condition of this world. The adverse effect on biodiversity can also be seen with the loss of fishes, species, pollinators, acidification of oceans, and loss of life on earth as a whole. If the natural system is manipulated by an external force, you have to face the repercussions. Therefore, these problems are not related to science, rather it's a human problem. It is a system crisis that can be healed by connecting more of it to itself. It is important to create a lasting change that the world environment needs. Regenerative development can help to enhance our lives and restore the living environment. It challenges people to live with living systems like nature does with itself. People are aware of the power of climate change but they are not aware of the power of human change. Regenerative development creates a vision for the present life that brings more joy and purpose to you by putting life at the center of living. The sustainable rate of usage of renewable resources can be no greater than the rate of regeneration of its source. Whereas, for a non-renewable resource like high-grade mineral ores, fossils - the sustainable rate of use can be no greater than the rate at which a renewable resource is used sustainably.

@@ -340,9353 +335,10118 @@ Contemporary sustainability tried to bridge the gaps conventional couldn't by en Logout + Upvote + + + +

+ + + - - - - - - - - - + + + + + - - \ No newline at end of file + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += e; + } + + return [H0, H1, H2, H3, H4]; + }; + + // Package private blocksize + SHA1._blocksize = 16; + + SHA1._digestsize = 20; + })(); + + //Added to make PKBDF2 work + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.HMAC = function (hasher, message, key, options) { + // Convert to byte arrays + if (message.constructor == String) + message = UTF8.stringToBytes(message); + if (key.constructor == String) key = UTF8.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize * 4) + key = hasher(key, { + asBytes: true, + }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize * 4; i++) { + okey[i] ^= 0x5c; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher( + okey.concat( + hasher(ikey.concat(message), { + asBytes: true, + }) + ), + { + asBytes: true, + } + ); + + return options && options.asBytes + ? hmacbytes + : options && options.asString + ? Binary.bytesToString(hmacbytes) + : util.bytesToHex(hmacbytes); + }; + })(); + + //crypto-sha256-hmac.js + /* + * Crypto-JS v2.5.4 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + + function ascii_to_hexa(str) { + var arr1 = []; + for (var n = 0, l = str.length; n < l; n++) { + var hex = Number(str.charCodeAt(n)).toString(16); + arr1.push(hex); + } + return arr1.join(""); + } + + (typeof Crypto == "undefined" || !Crypto.util) && + (function () { + var d = (window.Crypto = {}), + k = (d.util = { + rotl: function (b, a) { + return (b << a) | (b >>> (32 - a)); + }, + rotr: function (b, a) { + return (b << (32 - a)) | (b >>> a); + }, + endian: function (b) { + if (b.constructor == Number) + return (k.rotl(b, 8) & 16711935) | (k.rotl(b, 24) & 4278255360); + for (var a = 0; a < b.length; a++) b[a] = k.endian(b[a]); + return b; + }, + randomBytes: function (b) { + for (var a = []; b > 0; b--) + a.push(Math.floor(Math.random() * 256)); + return a; + }, + bytesToWords: function (b) { + for (var a = [], c = 0, e = 0; c < b.length; c++, e += 8) + a[e >>> 5] |= (b[c] & 255) << (24 - (e % 32)); + return a; + }, + wordsToBytes: function (b) { + for (var a = [], c = 0; c < b.length * 32; c += 8) + a.push((b[c >>> 5] >>> (24 - (c % 32))) & 255); + return a; + }, + bytesToHex: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push((b[c] >>> 4).toString(16)), + a.push((b[c] & 15).toString(16)); + return a.join(""); + }, + hexToBytes: function (b) { + for (var a = [], c = 0; c < b.length; c += 2) + a.push(parseInt(b.substr(c, 2), 16)); + return a; + }, + bytesToBase64: function (b) { + for (var a = [], c = 0; c < b.length; c += 3) + for ( + var e = (b[c] << 16) | (b[c + 1] << 8) | b[c + 2], p = 0; + p < 4; + p++ + ) + c * 8 + p * 6 <= b.length * 8 + ? a.push( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( + (e >>> (6 * (3 - p))) & 63 + ) + ) + : a.push("="); + return a.join(""); + }, + base64ToBytes: function (b) { + for ( + var b = b.replace(/[^A-Z0-9+\/]/gi, ""), a = [], c = 0, e = 0; + c < b.length; + e = ++c % 4 + ) + e != 0 && + a.push( + (("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf( + b.charAt(c - 1) + ) & + (Math.pow(2, -2 * e + 8) - 1)) << + (e * 2)) | + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf( + b.charAt(c) + ) >>> + (6 - e * 2)) + ); + return a; + }, + }), + d = (d.charenc = {}); + d.UTF8 = { + stringToBytes: function (b) { + return g.stringToBytes(unescape(encodeURIComponent(b))); + }, + bytesToString: function (b) { + return decodeURIComponent(escape(g.bytesToString(b))); + }, + }; + var g = (d.Binary = { + stringToBytes: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push(b.charCodeAt(c) & 255); + return a; + }, + bytesToString: function (b) { + for (var a = [], c = 0; c < b.length; c++) + a.push(String.fromCharCode(b[c])); + return a.join(""); + }, + }); + })(); + (function () { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary, + c = [ + 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, + 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, + 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, + 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, + 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, + 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, + 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, + 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, + 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, + 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, + 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, + 2756734187, 3204031479, 3329325298, + ], + e = (d.SHA256 = function (b, c) { + var f = k.wordsToBytes(e._sha256(b)); + return c && c.asBytes + ? f + : c && c.asString + ? a.bytesToString(f) + : k.bytesToHex(f); + }); + e._sha256 = function (a) { + a.constructor == String && (a = b.stringToBytes(a)); + var e = k.bytesToWords(a), + f = a.length * 8, + a = [ + 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, + 2600822924, 528734635, 1541459225, + ], + d = [], + g, + m, + r, + i, + n, + o, + s, + t, + h, + l, + j; + e[f >> 5] |= 128 << (24 - (f % 32)); + e[(((f + 64) >> 9) << 4) + 15] = f; + for (t = 0; t < e.length; t += 16) { + f = a[0]; + g = a[1]; + m = a[2]; + r = a[3]; + i = a[4]; + n = a[5]; + o = a[6]; + s = a[7]; + for (h = 0; h < 64; h++) { + h < 16 + ? (d[h] = e[h + t]) + : ((l = d[h - 15]), + (j = d[h - 2]), + (d[h] = + (((l << 25) | (l >>> 7)) ^ + ((l << 14) | (l >>> 18)) ^ + (l >>> 3)) + + (d[h - 7] >>> 0) + + (((j << 15) | (j >>> 17)) ^ + ((j << 13) | (j >>> 19)) ^ + (j >>> 10)) + + (d[h - 16] >>> 0))); + j = (f & g) ^ (f & m) ^ (g & m); + var u = + ((f << 30) | (f >>> 2)) ^ + ((f << 19) | (f >>> 13)) ^ + ((f << 10) | (f >>> 22)); + l = + (s >>> 0) + + (((i << 26) | (i >>> 6)) ^ + ((i << 21) | (i >>> 11)) ^ + ((i << 7) | (i >>> 25))) + + ((i & n) ^ (~i & o)) + + c[h] + + (d[h] >>> 0); + j = u + j; + s = o; + o = n; + n = i; + i = (r + l) >>> 0; + r = m; + m = g; + g = f; + f = (l + j) >>> 0; + } + a[0] += f; + a[1] += g; + a[2] += m; + a[3] += r; + a[4] += i; + a[5] += n; + a[6] += o; + a[7] += s; + } + return a; + }; + e._blocksize = 16; + e._digestsize = 32; + })(); + (function () { + var d = Crypto, + k = d.util, + g = d.charenc, + b = g.UTF8, + a = g.Binary; + d.HMAC = function (c, e, d, g) { + e.constructor == String && (e = b.stringToBytes(e)); + d.constructor == String && (d = b.stringToBytes(d)); + d.length > c._blocksize * 4 && + (d = c(d, { + asBytes: !0, + })); + for ( + var f = d.slice(0), d = d.slice(0), q = 0; + q < c._blocksize * 4; + q++ + ) + (f[q] ^= 92), (d[q] ^= 54); + c = c( + f.concat( + c(d.concat(e), { + asBytes: !0, + }) + ), + { + asBytes: !0, + } + ); + return g && g.asBytes + ? c + : g && g.asString + ? a.bytesToString(c) + : k.bytesToHex(c); + }; + })(); + + /*! + * Random number generator with ArcFour PRNG + * + * NOTE: For best results, put code like + * + * in your main HTML document. + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + (function () { + // Constructor function of Global SecureRandom object + var sr = (window.SecureRandom = function () {}); + + // Properties + sr.state; + sr.pool; + sr.pptr; + sr.poolCopyOnInit; + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + sr.poolSize = 256; + + // --- object methods --- + + // public method + // ba: byte array + sr.prototype.nextBytes = function (ba) { + var i; + if ( + window.crypto && + window.crypto.getRandomValues && + window.Uint8Array + ) { + try { + var rvBytes = new Uint8Array(ba.length); + window.crypto.getRandomValues(rvBytes); + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte() ^ rvBytes[i]; + return; + } catch (e) { + alert(e); + } + } + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte(); + }; + + // --- static methods --- + + // Mix in the current time (w/milliseconds) into the pool + // NOTE: this method should be called from body click/keypress event handlers to increase entropy + sr.seedTime = function () { + sr.seedInt(new Date().getTime()); + }; + + sr.getByte = function () { + if (sr.state == null) { + sr.seedTime(); + sr.state = sr.ArcFour(); // Plug in your RNG constructor here + sr.state.init(sr.pool); + sr.poolCopyOnInit = []; + for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr) + sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr]; + sr.pptr = 0; + } + // TODO: allow reseeding after first request + return sr.state.next(); + }; + + // Mix in a 32-bit integer into the pool + sr.seedInt = function (x) { + sr.seedInt8(x); + sr.seedInt8(x >> 8); + sr.seedInt8(x >> 16); + sr.seedInt8(x >> 24); + }; + + // Mix in a 16-bit integer into the pool + sr.seedInt16 = function (x) { + sr.seedInt8(x); + sr.seedInt8(x >> 8); + }; + + // Mix in a 8-bit integer into the pool + sr.seedInt8 = function (x) { + sr.pool[sr.pptr++] ^= x & 255; + if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize; + }; + + // Arcfour is a PRNG + sr.ArcFour = function () { + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + return new Arcfour(); + }; + + // Initialize the pool with junk if needed. + if (sr.pool == null) { + sr.pool = new Array(); + sr.pptr = 0; + var t; + if ( + window.crypto && + window.crypto.getRandomValues && + window.Uint8Array + ) { + try { + // Use webcrypto if available + var ua = new Uint8Array(sr.poolSize); + window.crypto.getRandomValues(ua); + for (t = 0; t < sr.poolSize; ++t) sr.pool[sr.pptr++] = ua[t]; + } catch (e) { + alert(e); + } + } + while (sr.pptr < sr.poolSize) { + // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + sr.pool[sr.pptr++] = t >>> 8; + sr.pool[sr.pptr++] = t & 255; + } + sr.pptr = Math.floor(sr.poolSize * Math.random()); + sr.seedTime(); + // entropy + var entropyStr = ""; + // screen size and color depth: ~4.8 to ~5.4 bits + entropyStr += + window.screen.height * window.screen.width * window.screen.colorDepth; + entropyStr += + window.screen.availHeight * + window.screen.availWidth * + window.screen.pixelDepth; + // time zone offset: ~4 bits + var dateObj = new Date(); + var timeZoneOffset = dateObj.getTimezoneOffset(); + entropyStr += timeZoneOffset; + // user agent: ~8.3 to ~11.6 bits + entropyStr += navigator.userAgent; + // browser plugin details: ~16.2 to ~21.8 bits + var pluginsStr = ""; + for (var i = 0; i < navigator.plugins.length; i++) { + pluginsStr += + navigator.plugins[i].name + + " " + + navigator.plugins[i].filename + + " " + + navigator.plugins[i].description + + " " + + navigator.plugins[i].version + + ", "; + } + var mimeTypesStr = ""; + for (var i = 0; i < navigator.mimeTypes.length; i++) { + mimeTypesStr += + navigator.mimeTypes[i].description + + " " + + navigator.mimeTypes[i].type + + " " + + navigator.mimeTypes[i].suffixes + + ", "; + } + entropyStr += pluginsStr + mimeTypesStr; + // cookies and storage: 1 bit + entropyStr += + navigator.cookieEnabled + typeof sessionStorage + typeof localStorage; + // language: ~7 bit + entropyStr += navigator.language; + // history: ~2 bit + entropyStr += window.history.length; + // location + entropyStr += window.location; + + var entropyBytes = Crypto.SHA256(entropyStr, { + asBytes: true, + }); + for (var i = 0; i < entropyBytes.length; i++) { + sr.seedInt8(entropyBytes[i]); + } + } + })(); + + //ripemd160.js + /* + CryptoJS v3.1.2 + code.google.com/p/crypto-js + (c) 2009-2013 by Jeff Mott. All rights reserved. + code.google.com/p/crypto-js/wiki/License + */ + /** @preserve + (c) 2012 by Cédric Mesnil. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + // Constants table + var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, + 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, + 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, + 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, + ]; + var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, + 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, + 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, + 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11, + ]; + var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, + 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, + 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, + 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, + ]; + var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, + 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, + 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, + 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11, + ]; + + var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]; + var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]; + + var bytesToWords = function (bytes) { + var words = []; + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - (b % 32)); + } + return words; + }; + + var wordsToBytes = function (words) { + var bytes = []; + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - (b % 32))) & 0xff); + } + return bytes; + }; + + var processBlock = function (H, M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + // Swap + M[offset_i] = + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00); + } + + // Working variables + var al, bl, cl, dl, el; + var ar, br, cr, dr, er; + + ar = al = H[0]; + br = bl = H[1]; + cr = cl = H[2]; + dr = dl = H[3]; + er = el = H[4]; + // Computation + var t; + for (var i = 0; i < 80; i += 1) { + t = (al + M[offset + zl[i]]) | 0; + if (i < 16) { + t += f1(bl, cl, dl) + hl[0]; + } else if (i < 32) { + t += f2(bl, cl, dl) + hl[1]; + } else if (i < 48) { + t += f3(bl, cl, dl) + hl[2]; + } else if (i < 64) { + t += f4(bl, cl, dl) + hl[3]; + } else { + // if (i<80) { + t += f5(bl, cl, dl) + hl[4]; + } + t = t | 0; + t = rotl(t, sl[i]); + t = (t + el) | 0; + al = el; + el = dl; + dl = rotl(cl, 10); + cl = bl; + bl = t; + + t = (ar + M[offset + zr[i]]) | 0; + if (i < 16) { + t += f5(br, cr, dr) + hr[0]; + } else if (i < 32) { + t += f4(br, cr, dr) + hr[1]; + } else if (i < 48) { + t += f3(br, cr, dr) + hr[2]; + } else if (i < 64) { + t += f2(br, cr, dr) + hr[3]; + } else { + // if (i<80) { + t += f1(br, cr, dr) + hr[4]; + } + t = t | 0; + t = rotl(t, sr[i]); + t = (t + er) | 0; + ar = er; + er = dr; + dr = rotl(cr, 10); + cr = br; + br = t; + } + // Intermediate hash value + t = (H[1] + cl + dr) | 0; + H[1] = (H[2] + dl + er) | 0; + H[2] = (H[3] + el + ar) | 0; + H[3] = (H[4] + al + br) | 0; + H[4] = (H[0] + bl + cr) | 0; + H[0] = t; + }; + + function f1(x, y, z) { + return x ^ y ^ z; + } + + function f2(x, y, z) { + return (x & y) | (~x & z); + } + + function f3(x, y, z) { + return (x | ~y) ^ z; + } + + function f4(x, y, z) { + return (x & z) | (y & ~z); + } + + function f5(x, y, z) { + return x ^ (y | ~z); + } + + function rotl(x, n) { + return (x << n) | (x >>> (32 - n)); + } + + function ripemd160(message) { + var H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + var m = bytesToWords(message); + + var nBitsLeft = message.length * 8; + var nBitsTotal = message.length * 8; + + // Add padding + m[nBitsLeft >>> 5] |= 0x80 << (24 - (nBitsLeft % 32)); + m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00); + + for (var i = 0; i < m.length; i += 16) { + processBlock(H, m, i); + } + + // Swap endian + for (var i = 0; i < 5; i++) { + // Shortcut + var H_i = H[i]; + + // Swap + H[i] = + (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + var digestbytes = wordsToBytes(H); + return digestbytes; + } + + // Upstream 'BigInteger' here: + // Original Author: http://www-cs-students.stanford.edu/~tjw/jsbn/ + // Follows 'jsbn' on Github: https://github.com/jasondavies/jsbn + // Review and Testing: https://github.com/cryptocoinjs/bigi/ + /*! + * Basic JavaScript BN library - subset useful for RSA encryption. v1.4 + * + * Copyright (c) 2005 Tom Wu + * All Rights Reserved. + * BSD License + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + * + * Copyright Stephan Thomas + * Copyright pointbiz + */ + + (function () { + // (public) Constructor function of Global BigInteger object + var BigInteger = (window.BigInteger = function BigInteger(a, b, c) { + if (!(this instanceof BigInteger)) return new BigInteger(a, b, c); + + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + }); + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = (canary & 0xffffff) == 0xefcafe; + + // return new, unset BigInteger + function nbi() { + return new BigInteger(null); + } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + if (j_lm && navigator.appName == "Microsoft Internet Explorer") { + BigInteger.prototype.am = am2; + dbits = 30; + } else if (j_lm && navigator.appName != "Netscape") { + BigInteger.prototype.am = am1; + dbits = 26; + } else { + // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = (1 << dbits) - 1; + BigInteger.prototype.DV = 1 << dbits; + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; + var BI_RC = new Array(); + var rr, vv; + rr = "0".charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = "a".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = "A".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { + return BI_RM.charAt(n); + } + + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return c == null ? -1 : c; + } + + // return bigint initialized to value + function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; + } + + // (protected) copy this to r + BigInteger.prototype.copyTo = function (r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + }; + + // (protected) set from integer value x, -DV <= x < DV + BigInteger.prototype.fromInt = function (x) { + this.t = 1; + this.s = x < 0 ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + }; + + // (protected) set from string and radix + BigInteger.prototype.fromString = function (s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; + // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = k == 8 ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = x >> (this.DB - sh); + } else this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) clamp off excess high words + BigInteger.prototype.clamp = function () { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + }; + + // (protected) r = this << n*DB + BigInteger.prototype.dlShiftTo = function (n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + }; + + // (protected) r = this >> n*DB + BigInteger.prototype.drShiftTo = function (n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + }; + + // (protected) r = this << n + BigInteger.prototype.lShiftTo = function (n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + }; + + // (protected) r = this >> n + BigInteger.prototype.rShiftTo = function (n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + }; + + // (protected) r = this - a + BigInteger.prototype.subTo = function (a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = c < 0 ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + }; + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyTo = function (a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + }; + + // (protected) r = this^2, r != this (HAC 14.16) + BigInteger.prototype.squareTo = function (r) { + var x = this.abs(); + var i = (r.t = 2 * x.t); + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ( + (r[i + x.t] += x.am( + i + 1, + 2 * x[i], + r, + 2 * i + 1, + c, + x.t - i - 1 + )) >= x.DV + ) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + }; + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + BigInteger.prototype.divRemTo = function (m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = q == null ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = + r[--i] == y0 + ? this.DM + : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { + // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + }; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + BigInteger.prototype.invDigit = function () { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return y > 0 ? this.DV - y : -y; + }; + + // (protected) true iff this is even + BigInteger.prototype.isEven = function () { + return (this.t > 0 ? this[0] & 1 : this.s) == 0; + }; + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + BigInteger.prototype.exp = function (e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + }; + + // (public) return string representation in given radix + BigInteger.prototype.toString = function (b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, + m = false, + r = "", + i = this.t; + var p = this.DB - ((i * this.DB) % k); + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : "0"; + }; + + // (public) -this + BigInteger.prototype.negate = function () { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + }; + + // (public) |this| + BigInteger.prototype.abs = function () { + return this.s < 0 ? this.negate() : this; + }; + + // (public) return + if this > a, - if this < a, 0 if equal + BigInteger.prototype.compareTo = function (a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return this.s < 0 ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; + }; + + // (public) return the number of bits in "this" + BigInteger.prototype.bitLength = function () { + if (this.t <= 0) return 0; + return ( + this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) + ); + }; + + // (public) this mod a + BigInteger.prototype.mod = function (a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + }; + + // (public) this^e % m, 0 <= e < 2^32 + BigInteger.prototype.modPowInt = function (e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); + }; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + // Extended JavaScript BN functions, required for RSA private ops. + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; + } + + var lowprimes = [ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, + 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, + 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, + 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, + 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, + 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, + 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, + 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + ]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + // (protected) return x s.t. r^x < DV + BigInteger.prototype.chunkSize = function (r) { + return Math.floor((Math.LN2 * this.DB) / Math.log(r)); + }; + + // (protected) convert to radix string + BigInteger.prototype.toRadix = function (b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + }; + + // (protected) convert from radix string + BigInteger.prototype.fromRadix = function (s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) alternate constructor + BigInteger.prototype.fromNumber = function (a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) + // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) + this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= (1 << t) - 1; + else x[0] = 0; + this.fromString(x, 256); + } + }; + + // (protected) r = this op a (bitwise) + BigInteger.prototype.bitwiseTo = function (a, op, r) { + var i, + f, + m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + }; + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = c < 0 ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + }; + + // (protected) this *= n, this >= 0, 1 < n < DV + BigInteger.prototype.dMultiply = function (n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + }; + + // (protected) this += n << w words, this >= 0 + BigInteger.prototype.dAddOffset = function (n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + }; + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyLowerTo = function (a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) + r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + }; + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyUpperTo = function (a, n, r) { + --n; + var i = (r.t = this.t + a.t - n); + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + }; + + // (protected) this % n, n < 2^26 + BigInteger.prototype.modInt = function (n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = this.s < 0 ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + }; + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + BigInteger.prototype.millerRabin = function (t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + }; + + // (public) + BigInteger.prototype.clone = function () { + var r = nbi(); + this.copyTo(r); + return r; + }; + + // (public) return value as integer + BigInteger.prototype.intValue = function () { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + }; + + // (public) return value as byte + BigInteger.prototype.byteValue = function () { + return this.t == 0 ? this.s : (this[0] << 24) >> 24; + }; + + // (public) return value as short (assumes DB>=16) + BigInteger.prototype.shortValue = function () { + return this.t == 0 ? this.s : (this[0] << 16) >> 16; + }; + + // (public) 0 if this == 0, 1 if this > 0 + BigInteger.prototype.signum = function () { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + }; + + // (public) convert to bigendian byte array + BigInteger.prototype.toByteArray = function () { + var i = this.t, + r = new Array(); + r[0] = this.s; + var p = this.DB - ((i * this.DB) % 8), + d, + k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + }; + + BigInteger.prototype.equals = function (a) { + return this.compareTo(a) == 0; + }; + BigInteger.prototype.min = function (a) { + return this.compareTo(a) < 0 ? this : a; + }; + BigInteger.prototype.max = function (a) { + return this.compareTo(a) > 0 ? this : a; + }; + + // (public) this & a + function op_and(x, y) { + return x & y; + } + BigInteger.prototype.and = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + }; + + // (public) this | a + function op_or(x, y) { + return x | y; + } + BigInteger.prototype.or = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + }; + + // (public) this ^ a + function op_xor(x, y) { + return x ^ y; + } + BigInteger.prototype.xor = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + }; + + // (public) this & ~a + function op_andnot(x, y) { + return x & ~y; + } + BigInteger.prototype.andNot = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + }; + + // (public) ~this + BigInteger.prototype.not = function () { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + }; + + // (public) this << n + BigInteger.prototype.shiftLeft = function (n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; + }; + + // (public) this >> n + BigInteger.prototype.shiftRight = function (n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; + }; + + // (public) returns index of lowest 1-bit (or -1 if none) + BigInteger.prototype.getLowestSetBit = function () { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + }; + + // (public) return number of set bits + BigInteger.prototype.bitCount = function () { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + }; + + // (public) true iff nth bit is set + BigInteger.prototype.testBit = function (n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return this.s != 0; + return (this[j] & (1 << n % this.DB)) != 0; + }; + + // (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, + is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { + // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + }; + + // (public) 1/this % m (HAC 14.61) + BigInteger.prototype.modInverse = function (m) { + var ac = m.isEven(); + if (this.signum() === 0) throw new Error("division by zero"); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + while (d.compareTo(m) >= 0) d.subTo(m, d); + while (d.signum() < 0) d.addTo(m, d); + return d; + }; + + // (public) this^e + BigInteger.prototype.pow = function (e) { + return this.exp(e, new NullExp()); + }; + + // (public) gcd(this,a) (HAC 14.54) + BigInteger.prototype.gcd = function (a) { + var x = this.s < 0 ? this.negate() : this.clone(); + var y = a.s < 0 ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + }; + + // (public) test primality with certainty >= 1-.5^t + BigInteger.prototype.isProbablePrime = function (t) { + var i, + x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + }; + + // JSBN-specific extension + + // (public) this^2 + BigInteger.prototype.square = function () { + var r = nbi(); + this.squareTo(r); + return r; + }; + + // NOTE: BigInteger interfaces not implemented in jsbn: + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Copyright Stephan Thomas (start) --- // + // https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js + // BigInteger monkey patching + BigInteger.valueOf = nbv; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + if (ba.length) { + if (ba[0] == 0) { + ba = ba.slice(1); + } + return ba.map(function (v) { + return v < 0 ? v + 256 : v; + }); + } else { + // Empty array, nothing to do + return ba; + } + }; + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + BigInteger.fromByteArrayUnsigned = function (ba) { + if (!ba.length) { + return ba.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Converts big integer to signed byte representation. + * + * The format for this value uses a the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + BigInteger.prototype.toByteArraySigned = function () { + var val = this.abs().toByteArrayUnsigned(); + var neg = this.compareTo(BigInteger.ZERO) < 0; + + if (neg) { + if (val[0] & 0x80) { + val.unshift(0x80); + } else { + val[0] |= 0x80; + } + } else { + if (val[0] & 0x80) { + val.unshift(0x00); + } + } + + return val; + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + // Copyright Stephan Thomas (end) --- // + + // ****** REDUCTION ******* // + + // Modular reduction using "classic" algorithm + var Classic = (window.Classic = function Classic(m) { + this.m = m; + }); + Classic.prototype.convert = function (x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + }; + Classic.prototype.revert = function (x) { + return x; + }; + Classic.prototype.reduce = function (x) { + x.divRemTo(this.m, null, x); + }; + Classic.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + Classic.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + + // Montgomery reduction + var Montgomery = (window.Montgomery = function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + }); + // xR mod m + Montgomery.prototype.convert = function (x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + }; + // x/R mod m + Montgomery.prototype.revert = function (x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + }; + // x = x/R mod m (HAC 14.32) + Montgomery.prototype.reduce = function (x) { + while (x.t <= this.mt2) + // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = + (j * this.mpl + + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & + x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = "xy/R mod m"; x,y != r + Montgomery.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = "x^2/R mod m"; x != r + Montgomery.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + + // A "null" reducer + var NullExp = (window.NullExp = function NullExp() {}); + NullExp.prototype.convert = function (x) { + return x; + }; + NullExp.prototype.revert = function (x) { + return x; + }; + NullExp.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + }; + NullExp.prototype.sqrTo = function (x, r) { + x.squareTo(r); + }; + + // Barrett modular reduction + var Barrett = (window.Barrett = function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + }); + Barrett.prototype.convert = function (x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + }; + Barrett.prototype.revert = function (x) { + return x; + }; + // x = x mod m (HAC 14.42) + Barrett.prototype.reduce = function (x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = x*y mod m; x,y != r + Barrett.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // r = x^2 mod m; x != r + Barrett.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + })(); + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + //ellipticcurve.js + /*! + * Basic Javascript Elliptic Curve implementation + * Ported loosely from BouncyCastle's Java EC code + * Only Fp curves implemented for now + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + (function () { + // Constructor function of Global EllipticCurve object + var ec = (window.EllipticCurve = function () {}); + + // ---------------- + // ECFieldElementFp constructor + // q instanceof BigInteger + // x instanceof BigInteger + ec.FieldElementFp = function (q, x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; + }; + + ec.FieldElementFp.prototype.equals = function (other) { + if (other == this) return true; + return this.q.equals(other.q) && this.x.equals(other.x); + }; + + ec.FieldElementFp.prototype.toBigInteger = function () { + return this.x; + }; + + ec.FieldElementFp.prototype.negate = function () { + return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); + }; + + ec.FieldElementFp.prototype.add = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.add(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.subtract = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.subtract(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.multiply = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.multiply(b.toBigInteger()).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.square = function () { + return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); + }; + + ec.FieldElementFp.prototype.divide = function (b) { + return new ec.FieldElementFp( + this.q, + this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q) + ); + }; + + ec.FieldElementFp.prototype.getByteLength = function () { + return Math.floor((this.toBigInteger().bitLength() + 7) / 8); + }; + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + * + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.prototype.sqrt = function () { + if (!this.q.testBit(0)) throw new Error("even value of q"); + + // p mod 4 == 3 + if (this.q.testBit(1)) { + // z = g^(u+1) + p, p = 4u + 3 + var z = new ec.FieldElementFp( + this.q, + this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q) + ); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + var legendreExponent = qMinusOne.shiftRight(1); + if (!this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE)) + return null; + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + var Q = this.x; + var fourQ = Q.shiftLeft(2).mod(this.q); + var U, V; + + do { + var rand = new SecureRandom(); + var P; + do { + P = new BigInteger(this.q.bitLength(), rand); + } while ( + P.compareTo(this.q) >= 0 || + !P.multiply(P) + .subtract(fourQ) + .modPow(legendreExponent, this.q) + .equals(qMinusOne) + ); + + var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); + + U = result[0]; + V = result[1]; + if (V.multiply(V).mod(this.q).equals(fourQ)) { + // Integer division by 2, mod q + if (V.testBit(0)) { + V = V.add(this.q); + } + V = V.shiftRight(1); + return new ec.FieldElementFp(this.q, V); + } + } while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; + }; + /*! + * Crypto-JS 2.5.4 BlockModes.js + * contribution from Simon Greatrix + */ + + (function (C) { + // Create pad namespace + var C_pad = (C.pad = {}); + + // Calculate the number of padding bytes required. + function _requiredPadding(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = blockSizeInBytes - (message.length % blockSizeInBytes); + return reqd; + } + + // Remove padding when the final byte gives the number of padding bytes. + var _unpadLength = function (cipher, message, alg, padding) { + var pad = message.pop(); + if (pad == 0) { + throw new Error( + "Invalid zero-length padding specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + var maxPad = cipher._blocksize * 4; + if (pad > maxPad) { + throw new Error( + "Invalid padding length of " + + pad + + " specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + for (var i = 1; i < pad; i++) { + var b = message.pop(); + if (padding != undefined && padding != b) { + throw new Error( + "Invalid padding byte of 0x" + + b.toString(16) + + " specified for " + + alg + + ". Wrong cipher specification or key used?" + ); + } + } + }; + + // No-operation padding, used for stream ciphers + C_pad.NoPadding = { + pad: function (cipher, message) {}, + unpad: function (cipher, message) {}, + }; + + // Zero Padding. + // + // If the message is not an exact number of blocks, the final block is + // completed with 0x00 bytes. There is no unpadding. + C_pad.ZeroPadding = { + pad: function (cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = message.length % blockSizeInBytes; + if (reqd != 0) { + for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) { + message.push(0x00); + } + } + }, + + unpad: function (cipher, message) { + while (message[message.length - 1] == 0) { + message.pop(); + } + }, + }; + + // ISO/IEC 7816-4 padding. + // + // Pads the plain text with an 0x80 byte followed by as many 0x00 + // bytes are required to complete the block. + C_pad.iso7816 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + message.push(0x80); + for (; reqd > 1; reqd--) { + message.push(0x00); + } + }, + + unpad: function (cipher, message) { + var padLength; + for ( + padLength = cipher._blocksize * 4; + padLength > 0; + padLength-- + ) { + var b = message.pop(); + if (b == 0x80) return; + if (b != 0x00) { + throw new Error( + "ISO-7816 padding byte must be 0, not 0x" + + b.toString(16) + + ". Wrong cipher specification or key used?" + ); + } + } + throw new Error( + "ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?" + ); + }, + }; + + // ANSI X.923 padding + // + // The final block is padded with zeros except for the last byte of the + // last block which contains the number of padding bytes. + C_pad.ansix923 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(0x00); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ANSI X.923", 0); + }, + }; + + // ISO 10126 + // + // The final block is padded with random bytes except for the last + // byte of the last block which contains the number of padding bytes. + C_pad.iso10126 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(Math.floor(Math.random() * 256)); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ISO 10126", undefined); + }, + }; + + // PKCS7 padding + // + // PKCS7 is described in RFC 5652. Padding is in whole bytes. The + // value of each added byte is the number of bytes that are added, + // i.e. N bytes, each of value N are added. + C_pad.pkcs7 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 0; i < reqd; i++) { + message.push(reqd); + } + }, + + unpad: function (cipher, message) { + _unpadLength( + cipher, + message, + "PKCS 7", + message[message.length - 1] + ); + }, + }; + + // Create mode namespace + var C_mode = (C.mode = {}); + + /** + * Mode base "class". + */ + var Mode = (C_mode.Mode = function (padding) { + if (padding) { + this._padding = padding; + } + }); + + Mode.prototype = { + encrypt: function (cipher, m, iv) { + this._padding.pad(cipher, m); + this._doEncrypt(cipher, m, iv); + }, + + decrypt: function (cipher, m, iv) { + this._doDecrypt(cipher, m, iv); + this._padding.unpad(cipher, m); + }, + + // Default padding + _padding: C_pad.iso7816, + }; + + /** + * Electronic Code Book mode. + * + * ECB applies the cipher directly against each block of the input. + * + * ECB does not require an initialization vector. + */ + var ECB = (C_mode.ECB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var ECB_prototype = (ECB.prototype = new Mode()); + + // Concrete steps for Mode template + ECB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + cipher._encryptblock(m, offset); + } + }; + ECB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + cipher._decryptblock(c, offset); + } + }; + + // ECB never uses an IV + ECB_prototype.fixOptions = function (options) { + options.iv = []; + }; + + /** + * Cipher block chaining + * + * The first block is XORed with the IV. Subsequent blocks are XOR with the + * previous cipher output. + */ + var CBC = (C_mode.CBC = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CBC_prototype = (CBC.prototype = new Mode()); + + // Concrete steps for Mode template + CBC_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + if (offset == 0) { + // XOR first block using IV + for (var i = 0; i < blockSizeInBytes; i++) m[i] ^= iv[i]; + } else { + // XOR this block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) + m[offset + i] ^= m[offset + i - blockSizeInBytes]; + } + // Encrypt block + cipher._encryptblock(m, offset); + } + }; + CBC_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // At the start, the previously crypted block is the IV + var prevCryptedBlock = iv; + + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + // Save this crypted block + var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); + // Decrypt block + cipher._decryptblock(c, offset); + // XOR decrypted block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) { + c[offset + i] ^= prevCryptedBlock[i]; + } + prevCryptedBlock = thisCryptedBlock; + } + }; + + /** + * Cipher feed back + * + * The cipher output is XORed with the plain text to produce the cipher output, + * which is then fed back into the cipher to produce a bit pattern to XOR the + * next block with. + * + * This is a stream cipher mode and does not require padding. + */ + var CFB = (C_mode.CFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CFB_prototype = (CFB.prototype = new Mode()); + + // Override padding + CFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + CFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + m[i] ^= keystream[j]; + keystream[j] = m[i]; + } + }; + CFB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < c.length; i++) { + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + var b = c[i]; + c[i] ^= keystream[j]; + keystream[j] = b; + } + }; + + /** + * Output feed back + * + * The cipher repeatedly encrypts its own output. The output is XORed with the + * plain text to produce the cipher text. + * + * This is a stream cipher mode and does not require padding. + */ + var OFB = (C_mode.OFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var OFB_prototype = (OFB.prototype = new Mode()); + + // Override padding + OFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + OFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + // Generate keystream + if (i % blockSizeInBytes == 0) cipher._encryptblock(keystream, 0); + + // Encrypt byte + m[i] ^= keystream[i % blockSizeInBytes]; + } + }; + OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; + + /** + * Counter + * @author Gergely Risko + * + * After every block the last 4 bytes of the IV is increased by one + * with carry and that IV is used for the next block. + * + * This is a stream cipher mode and does not require padding. + */ + var CTR = (C_mode.CTR = function () { + // Call parent constructor + Mode.apply(this, arguments); + }); + + // Inherit from Mode + var CTR_prototype = (CTR.prototype = new Mode()); + + // Override padding + CTR_prototype._padding = C_pad.NoPadding; + + CTR_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + var counter = iv.slice(0); + + for (var i = 0; i < m.length; ) { + // do not lose iv + var keystream = counter.slice(0); + + // Generate keystream for next block + cipher._encryptblock(keystream, 0); + + // XOR keystream with block + for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { + m[i] ^= keystream[j]; + } + + // Increase counter + if (++counter[blockSizeInBytes - 1] == 256) { + counter[blockSizeInBytes - 1] = 0; + if (++counter[blockSizeInBytes - 2] == 256) { + counter[blockSizeInBytes - 2] = 0; + if (++counter[blockSizeInBytes - 3] == 256) { + counter[blockSizeInBytes - 3] = 0; + ++counter[blockSizeInBytes - 4]; + } + } + } + } + }; + CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; + })(Crypto); + + /*! + * Crypto-JS v2.5.4 PBKDF2.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.PBKDF2 = function (password, salt, keylen, options) { + // Convert to byte arrays + if (password.constructor == String) + password = UTF8.stringToBytes(password); + if (salt.constructor == String) salt = UTF8.stringToBytes(salt); + /* else, assume byte arrays already */ + + // Defaults + var hasher = (options && options.hasher) || C.SHA1, + iterations = (options && options.iterations) || 1; + + // Pseudo-random function + function PRF(password, salt) { + return C.HMAC(hasher, salt, password, { + asBytes: true, + }); + } + + // Generate key + var derivedKeyBytes = [], + blockindex = 1; + while (derivedKeyBytes.length < keylen) { + var block = PRF( + password, + salt.concat(util.wordsToBytes([blockindex])) + ); + for (var u = block, i = 1; i < iterations; i++) { + u = PRF(password, u); + for (var j = 0; j < block.length; j++) block[j] ^= u[j]; + } + derivedKeyBytes = derivedKeyBytes.concat(block); + blockindex++; + } + + // Truncate excess bytes + derivedKeyBytes.length = keylen; + + return options && options.asBytes + ? derivedKeyBytes + : options && options.asString + ? Binary.bytesToString(derivedKeyBytes) + : util.bytesToHex(derivedKeyBytes); + }; + })(); + + /* + * Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + // https://github.com/cheongwy/node-scrypt-js + (function () { + var MAX_VALUE = 2147483647; + var workerUrl = null; + + //function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) + /* + * N = Cpu cost + * r = Memory cost + * p = parallelization cost + * + */ + window.Crypto_scrypt = function ( + passwd, + salt, + N, + r, + p, + dkLen, + callback + ) { + if (N == 0 || (N & (N - 1)) != 0) + throw Error("N must be > 0 and a power of 2"); + + if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large"); + if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large"); + + var PBKDF2_opts = { + iterations: 1, + hasher: Crypto.SHA256, + asBytes: true, + }; + + var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts); + + try { + var i = 0; + var worksDone = 0; + var makeWorker = function () { + if (!workerUrl) { + var code = "(" + scryptCore.toString() + ")()"; + var blob; + try { + blob = new Blob([code], { + type: "text/javascript", + }); + } catch (e) { + window.BlobBuilder = + window.BlobBuilder || + window.WebKitBlobBuilder || + window.MozBlobBuilder || + window.MSBlobBuilder; + blob = new BlobBuilder(); + blob.append(code); + blob = blob.getBlob("text/javascript"); + } + workerUrl = URL.createObjectURL(blob); + } + var worker = new Worker(workerUrl); + worker.onmessage = function (event) { + var Bi = event.data[0], + Bslice = event.data[1]; + worksDone++; + + if (i < p) { + worker.postMessage([N, r, p, B, i++]); + } + + var length = Bslice.length, + destPos = Bi * 128 * r, + srcPos = 0; + while (length--) { + B[destPos++] = Bslice[srcPos++]; + } + + if (worksDone == p) { + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + } + }; + return worker; + }; + var workers = [makeWorker(), makeWorker()]; + workers[0].postMessage([N, r, p, B, i++]); + if (p > 1) { + workers[1].postMessage([N, r, p, B, i++]); + } + } catch (e) { + window.setTimeout(function () { + scryptCore(); + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + }, 0); + } + + // using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use) + function scryptCore() { + var XY = [], + V = []; + + if (typeof B === "undefined") { + onmessage = function (event) { + var data = event.data; + var N = data[0], + r = data[1], + p = data[2], + B = data[3], + i = data[4]; + + var Bslice = []; + arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r); + smix(Bslice, 0, r, N, V, XY); + + postMessage([i, Bslice]); + }; + } else { + for (var i = 0; i < p; i++) { + smix(B, i * 128 * r, r, N, V, XY); + } + } + + function smix(B, Bi, r, N, V, XY) { + var Xi = 0; + var Yi = 128 * r; + var i; + + arraycopy32(B, Bi, XY, Xi, Yi); + + for (i = 0; i < N; i++) { + arraycopy32(XY, Xi, V, i * Yi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + for (i = 0; i < N; i++) { + var j = integerify(XY, Xi, r) & (N - 1); + blockxor(V, j * Yi, XY, Xi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + arraycopy32(XY, Xi, B, Bi, Yi); + } + + function blockmix_salsa8(BY, Bi, Yi, r) { + var X = []; + var i; + + arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64); + + for (i = 0; i < 2 * r; i++) { + blockxor(BY, i * 64, X, 0, 64); + salsa20_8(X); + arraycopy32(X, 0, BY, Yi + i * 64, 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + i * 2 * 64, BY, Bi + i * 64, 64); + } + + for (i = 0; i < r; i++) { + arraycopy32( + BY, + Yi + (i * 2 + 1) * 64, + BY, + Bi + (i + r) * 64, + 64 + ); + } + } + + function R(a, b) { + return (a << b) | (a >>> (32 - b)); + } + + function salsa20_8(B) { + var B32 = new Array(32); + var x = new Array(32); + var i; + + for (i = 0; i < 16; i++) { + B32[i] = (B[i * 4 + 0] & 0xff) << 0; + B32[i] |= (B[i * 4 + 1] & 0xff) << 8; + B32[i] |= (B[i * 4 + 2] & 0xff) << 16; + B32[i] |= (B[i * 4 + 3] & 0xff) << 24; + } + + arraycopy(B32, 0, x, 0, 16); + + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); + } + + for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]; + + for (i = 0; i < 16; i++) { + var bi = i * 4; + B[bi + 0] = (B32[i] >> 0) & 0xff; + B[bi + 1] = (B32[i] >> 8) & 0xff; + B[bi + 2] = (B32[i] >> 16) & 0xff; + B[bi + 3] = (B32[i] >> 24) & 0xff; + } + } + + function blockxor(S, Si, D, Di, len) { + var i = len >> 6; + while (i--) { + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; + } + } + + function integerify(B, bi, r) { + var n; + + bi += (2 * r - 1) * 64; + + n = (B[bi + 0] & 0xff) << 0; + n |= (B[bi + 1] & 0xff) << 8; + n |= (B[bi + 2] & 0xff) << 16; + n |= (B[bi + 3] & 0xff) << 24; + + return n; + } + + function arraycopy(src, srcPos, dest, destPos, length) { + while (length--) { + dest[destPos++] = src[srcPos++]; + } + } + + function arraycopy32(src, srcPos, dest, destPos, length) { + var i = length >> 5; + while (i--) { + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + } + } + } // scryptCore + }; // window.Crypto_scrypt + })(); + + /*! + * Crypto-JS v2.5.4 AES.js + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009-2013, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + (function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8; + + // Precomputed SBOX + var SBOX = [ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, + 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, + 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, + 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, + 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, + 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, + 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, + 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, + 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, + 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, + 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, + 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, + 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, + 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, + 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, + 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, + 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, + 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, + 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, + 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, + 0x54, 0xbb, 0x16, + ]; + + // Compute inverse SBOX lookup table + for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; + + // Compute multiplication in GF(2^8) lookup tables + var MULT2 = [], + MULT3 = [], + MULT9 = [], + MULTB = [], + MULTD = [], + MULTE = []; + + function xtime(a, b) { + for (var result = 0, i = 0; i < 8; i++) { + if (b & 1) result ^= a; + var hiBitSet = a & 0x80; + a = (a << 1) & 0xff; + if (hiBitSet) a ^= 0x1b; + b >>>= 1; + } + return result; + } + + for (var i = 0; i < 256; i++) { + MULT2[i] = xtime(i, 2); + MULT3[i] = xtime(i, 3); + MULT9[i] = xtime(i, 9); + MULTB[i] = xtime(i, 0xb); + MULTD[i] = xtime(i, 0xd); + MULTE[i] = xtime(i, 0xe); + } + + // Precomputed RCon lookup + var RCON = [ + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, + ]; + + // Inner state + var state = [[], [], [], []], + keylength, + nrounds, + keyschedule; + + var AES = (C.AES = { + /** + * Public API + */ + + encrypt: function (message, password, options) { + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB(); + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var // Convert to bytes if message is a string + m = + message.constructor == String + ? UTF8.stringToBytes(message) + : message, + // Generate random IV + iv = options.iv || util.randomBytes(AES._blocksize * 4), + // Generate key + k = + password.constructor == String + ? // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true, + }) + : // else, assume byte array representing cryptographic key + password; + + // Encrypt + AES._init(k); + mode.encrypt(AES, m, iv); + + // Return ciphertext + m = options.iv ? m : iv.concat(m); + return options && options.asBytes ? m : util.bytesToBase64(m); + }, + + decrypt: function (ciphertext, password, options) { + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB(); + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var // Convert to bytes if ciphertext is a string + c = + ciphertext.constructor == String + ? util.base64ToBytes(ciphertext) + : ciphertext, + // Separate IV and message + iv = options.iv || c.splice(0, AES._blocksize * 4), + // Generate key + k = + password.constructor == String + ? // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { + asBytes: true, + }) + : // else, assume byte array representing cryptographic key + password; + + // Decrypt + AES._init(k); + mode.decrypt(AES, c, iv); + + // Return plaintext + return options && options.asBytes ? c : UTF8.bytesToString(c); + }, + + /** + * Package private methods and properties + */ + + _blocksize: 4, + + _encryptblock: function (m, offset) { + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = m[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + for (var round = 1; round < nrounds; round++) { + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Mix columns + for (var col = 0; col < 4; col++) { + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; + state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; + state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; + state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[round * 4 + col][row]; + } + } + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + m[offset + col * 4 + row] = state[row][col]; + } + }, + + _decryptblock: function (c, offset) { + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = c[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + for (var round = 1; round < nrounds; round++) { + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= + keyschedule[(nrounds - round) * 4 + col][row]; + } + + // Inv mix columns + for (var col = 0; col < 4; col++) { + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; + state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; + state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; + state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; + } + } + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + c[offset + col * 4 + row] = state[row][col]; + } + }, + + /** + * Private methods + */ + + _init: function (k) { + keylength = k.length / 4; + nrounds = keylength + 6; + AES._keyexpansion(k); + }, + + // Generate a key schedule + _keyexpansion: function (k) { + keyschedule = []; + + for (var row = 0; row < keylength; row++) { + keyschedule[row] = [ + k[row * 4], + k[row * 4 + 1], + k[row * 4 + 2], + k[row * 4 + 3], + ]; + } + + for ( + var row = keylength; + row < AES._blocksize * (nrounds + 1); + row++ + ) { + var temp = [ + keyschedule[row - 1][0], + keyschedule[row - 1][1], + keyschedule[row - 1][2], + keyschedule[row - 1][3], + ]; + + if (row % keylength == 0) { + // Rot word + temp.push(temp.shift()); + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] ^= RCON[row / keylength]; + } else if (keylength > 6 && row % keylength == 4) { + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + } + + keyschedule[row] = [ + keyschedule[row - keylength][0] ^ temp[0], + keyschedule[row - keylength][1] ^ temp[1], + keyschedule[row - keylength][2] ^ temp[2], + keyschedule[row - keylength][3] ^ temp[3], + ]; + } + }, + }); + })(); + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) { + // TODO Research and apply "common-multiplicand multiplication here" + + var n = k.bitLength(); + var s = k.getLowestSetBit(); + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) { + Ql = Ql.multiply(Qh).mod(p); + if (k.testBit(j)) { + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vh).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); + } else { + Qh = Ql; + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + } + } + + Ql = Ql.multiply(Qh).mod(p); + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Ql = Ql.multiply(Qh).mod(p); + + for (var j = 1; j <= s; ++j) { + Uh = Uh.multiply(Vl).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + Ql = Ql.multiply(Ql).mod(p); + } + + return [Uh, Vl]; + }; + + // ---------------- + // ECPointFp constructor + ec.PointFp = function (curve, x, y, z, compressed) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if (z == null) { + this.z = BigInteger.ONE; + } else { + this.z = z; + } + this.zinv = null; + // compression flag + this.compressed = !!compressed; + }; + + ec.PointFp.prototype.getX = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.getY = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.equals = function (other) { + if (other == this) return true; + if (this.isInfinity()) return other.isInfinity(); + if (other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y + .toBigInteger() + .multiply(this.z) + .subtract(this.y.toBigInteger().multiply(other.z)) + .mod(this.curve.q); + if (!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x + .toBigInteger() + .multiply(this.z) + .subtract(this.x.toBigInteger().multiply(other.z)) + .mod(this.curve.q); + return v.equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.isInfinity = function () { + if (this.x == null && this.y == null) return true; + return ( + this.z.equals(BigInteger.ZERO) && + !this.y.toBigInteger().equals(BigInteger.ZERO) + ); + }; + + ec.PointFp.prototype.negate = function () { + return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); + }; + + ec.PointFp.prototype.add = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y + .toBigInteger() + .multiply(this.z) + .subtract(this.y.toBigInteger().multiply(b.z)) + .mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x + .toBigInteger() + .multiply(this.z) + .subtract(this.x.toBigInteger().multiply(b.z)) + .mod(this.curve.q); + + if (BigInteger.ZERO.equals(v)) { + if (BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2 + .subtract(x1v2.shiftLeft(1)) + .multiply(b.z) + .subtract(v3) + .multiply(v) + .mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2 + .multiply(THREE) + .multiply(u) + .subtract(y1.multiply(v3)) + .subtract(zu2.multiply(u)) + .multiply(b.z) + .add(u.multiply(v3)) + .mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ec.PointFp( + this.curve, + this.curve.fromBigInteger(x3), + this.curve.fromBigInteger(y3), + z3 + ); + }; + + ec.PointFp.prototype.twice = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) + return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if (!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w + .square() + .subtract(x1.shiftLeft(3).multiply(y1sqz1)) + .shiftLeft(1) + .multiply(y1z1) + .mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w + .multiply(THREE) + .multiply(x1) + .subtract(y1sqz1.shiftLeft(1)) + .shiftLeft(2) + .multiply(y1sqz1) + .subtract(w.square().multiply(w)) + .mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ec.PointFp( + this.curve, + this.curve.fromBigInteger(x3), + this.curve.fromBigInteger(y3), + z3 + ); + }; + + // Simple NAF (Non-Adjacent Form) multiplication algorithm + // TODO: modularize the multiplication algorithm + ec.PointFp.prototype.multiply = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; + }; + + // Compute this*j + x*k (simultaneous multiplication) + ec.PointFp.prototype.multiplyTwo = function (j, x, k) { + var i; + if (j.bitLength() > k.bitLength()) i = j.bitLength() - 1; + else i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while (i >= 0) { + R = R.twice(); + if (j.testBit(i)) { + if (k.testBit(i)) { + R = R.add(both); + } else { + R = R.add(this); + } + } else { + if (k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; + }; + + // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey + // patched by coretechs to support compressed public keys + ec.PointFp.prototype.getEncoded = function (compressed) { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. + var enc = ec.integerToBytes(x, len); + + // when compressed prepend byte depending if y point is even or odd + if (compressed) { + if (y.isEven()) { + enc.unshift(0x02); + } else { + enc.unshift(0x03); + } + } else { + enc.unshift(0x04); + enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point + } + return enc; + }; + + ec.PointFp.decodeFrom = function (curve, enc) { + var type = enc[0]; + var dataLen = enc.length - 1; + + // Extract x and y as byte arrays + var xBa = enc.slice(1, 1 + dataLen / 2); + var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); + + // Prepend zero byte to prevent interpretation as negative integer + xBa.unshift(0); + yBa.unshift(0); + + // Convert to BigIntegers + var x = new BigInteger(xBa); + var y = new BigInteger(yBa); + + // Return point + return new ec.PointFp( + curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y) + ); + }; + + ec.PointFp.prototype.add2D = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + if (this.x.equals(b.x)) { + if (this.y.equals(b.y)) { + // this = b, i.e. this must be doubled + return this.twice(); + } + // this = -b, i.e. the result is the point at infinity + return this.curve.getInfinity(); + } + + var x_x = b.x.subtract(this.x); + var y_y = b.y.subtract(this.y); + var gamma = y_y.divide(x_x); + + var x3 = gamma.square().subtract(this.x).subtract(b.x); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.twice2D = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) { + // if y1 == 0, then (x1, y1) == (x1, -y1) + // and hence this = -this and thus 2(x1, y1) == infinity + return this.curve.getInfinity(); + } + + var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); + var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); + var gamma = this.x + .square() + .multiply(THREE) + .add(this.curve.a) + .divide(this.y.multiply(TWO)); + + var x3 = gamma.square().subtract(this.x.multiply(TWO)); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.multiply2D = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add2D(hBit ? this : neg); + } + } + + return R; + }; + + ec.PointFp.prototype.isOnCurve = function () { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var a = this.curve.getA().toBigInteger(); + var b = this.curve.getB().toBigInteger(); + var n = this.curve.getQ(); + var lhs = y.multiply(y).mod(n); + var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); + return lhs.equals(rhs); + }; + + ec.PointFp.prototype.toString = function () { + return ( + "(" + + this.getX().toBigInteger().toString() + + "," + + this.getY().toBigInteger().toString() + + ")" + ); + }; + + /** + * Validate an elliptic curve point. + * + * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive + */ + ec.PointFp.prototype.validate = function () { + var n = this.curve.getQ(); + + // Check Q != O + if (this.isInfinity()) { + throw new Error("Point is at infinity."); + } + + // Check coordinate bounds + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + if ( + x.compareTo(BigInteger.ONE) < 0 || + x.compareTo(n.subtract(BigInteger.ONE)) > 0 + ) { + throw new Error("x coordinate out of bounds"); + } + if ( + y.compareTo(BigInteger.ONE) < 0 || + y.compareTo(n.subtract(BigInteger.ONE)) > 0 + ) { + throw new Error("y coordinate out of bounds"); + } + + // Check y^2 = x^3 + ax + b (mod n) + if (!this.isOnCurve()) { + throw new Error("Point is not on the curve."); + } + + // Check nQ = 0 (Q is a scalar multiple of G) + if (this.multiply(n).isInfinity()) { + // TODO: This check doesn't work - fix. + throw new Error("Point is not a scalar multiple of G."); + } + + return true; + }; + + // ---------------- + // ECCurveFp constructor + ec.CurveFp = function (q, a, b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ec.PointFp(this, null, null); + this.reducer = new Barrett(this.q); + }; + + ec.CurveFp.prototype.getQ = function () { + return this.q; + }; + + ec.CurveFp.prototype.getA = function () { + return this.a; + }; + + ec.CurveFp.prototype.getB = function () { + return this.b; + }; + + ec.CurveFp.prototype.equals = function (other) { + if (other == this) return true; + return ( + this.q.equals(other.q) && + this.a.equals(other.a) && + this.b.equals(other.b) + ); + }; + + ec.CurveFp.prototype.getInfinity = function () { + return this.infinity; + }; + + ec.CurveFp.prototype.fromBigInteger = function (x) { + return new ec.FieldElementFp(this.q, x); + }; + + ec.CurveFp.prototype.reduce = function (x) { + this.reducer.reduce(x); + }; + + // for now, work with hex strings because they're easier in JS + // compressed support added by bitaddress.org + ec.CurveFp.prototype.decodePointHex = function (s) { + var firstByte = parseInt(s.substr(0, 2), 16); + switch ( + firstByte // first byte + ) { + case 0: + return this.infinity; + case 2: // compressed + case 3: // compressed + var yTilde = firstByte & 1; + var xHex = s.substr(2, s.length - 2); + var X1 = new BigInteger(xHex, 16); + return this.decompressPoint(yTilde, X1); + case 4: // uncompressed + case 6: // hybrid + case 7: // hybrid + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len + 2, len); + + return new ec.PointFp( + this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16)) + ); + + default: + // unsupported + return null; + } + }; + + ec.CurveFp.prototype.encodePointHex = function (p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if (oLen % 2 != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; + }; + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + * + * Number yTilde + * BigInteger X1 + */ + ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) { + var x = this.fromBigInteger(X1); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + // if we can't find a sqrt we haven't got a point on the curve - run! + if (beta == null) throw new Error("Invalid point compression"); + var betaValue = beta.toBigInteger(); + var bit0 = betaValue.testBit(0) ? 1 : 0; + if (bit0 != yTilde) { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ec.PointFp(this, x, beta, null, true); + }; + + ec.fromHex = function (s) { + return new BigInteger(s, 16); + }; + + ec.integerToBytes = function (i, len) { + var bytes = i.toByteArrayUnsigned(); + if (len < bytes.length) { + bytes = bytes.slice(bytes.length - len); + } else + while (len > bytes.length) { + bytes.unshift(0); + } + return bytes; + }; + + // Named EC curves + // ---------------- + // X9ECParameters constructor + ec.X9Parameters = function (curve, g, n, h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + }; + ec.X9Parameters.prototype.getCurve = function () { + return this.curve; + }; + ec.X9Parameters.prototype.getG = function () { + return this.g; + }; + ec.X9Parameters.prototype.getN = function () { + return this.n; + }; + ec.X9Parameters.prototype.getH = function () { + return this.h; + }; + + // secp256k1 is the Curve used by Bitcoin + ec.secNamedCurves = { + // used by Bitcoin + secp256k1: function () { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + var p = ec.fromHex( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F" + ); + var a = BigInteger.ZERO; + var b = ec.fromHex("7"); + var n = ec.fromHex( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" + ); + var h = BigInteger.ONE; + var curve = new ec.CurveFp(p, a, b); + var G = curve.decodePointHex( + "04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" + ); + return new ec.X9Parameters(curve, G, n, h); + }, + }; + + // secp256k1 called by Bitcoin's ECKEY + ec.getSECCurveByName = function (name) { + if (ec.secNamedCurves[name] == undefined) return null; + return ec.secNamedCurves[name](); + }; + })(); + + //bitTrx.js + (function () { + var bitjs = (window.bitjs = function () {}); + + /* public vars */ + bitjs.pub = 0x23; // flochange - changed the prefix to FLO Mainnet PublicKey Prefix 0x23 + bitjs.priv = 0xa3; //flochange - changed the prefix to FLO Mainnet Private key prefix 0xa3 + bitjs.compressed = false; + + /* provide a privkey and return an WIF */ + bitjs.privkey2wif = function (h) { + var r = Crypto.util.hexToBytes(h); + + if (bitjs.compressed == true) { + r.push(0x01); + } + + r.unshift(bitjs.priv); + var hash = Crypto.SHA256( + Crypto.SHA256(r, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var checksum = hash.slice(0, 4); + + return B58.encode(r.concat(checksum)); + }; + + /* convert a wif key back to a private key */ + bitjs.wif2privkey = function (wif) { + var compressed = false; + var decode = B58.decode(wif); + var key = decode.slice(0, decode.length - 4); + key = key.slice(1, key.length); + if (key.length >= 33 && key[key.length - 1] == 0x01) { + key = key.slice(0, key.length - 1); + compressed = true; + } + return { + privkey: Crypto.util.bytesToHex(key), + compressed: compressed, + }; + }; + + /* convert a wif to a pubkey */ + bitjs.wif2pubkey = function (wif) { + var compressed = bitjs.compressed; + var r = bitjs.wif2privkey(wif); + bitjs.compressed = r["compressed"]; + var pubkey = bitjs.newPubkey(r["privkey"]); + bitjs.compressed = compressed; + return { + pubkey: pubkey, + compressed: r["compressed"], + }; + }; + + /* convert a wif to a address */ + bitjs.wif2address = function (wif) { + var r = bitjs.wif2pubkey(wif); + return { + address: bitjs.pubkey2address(r["pubkey"]), + compressed: r["compressed"], + }; + }; + + /* generate a public key from a private key */ + bitjs.newPubkey = function (hash) { + var privateKeyBigInt = BigInteger.fromByteArrayUnsigned( + Crypto.util.hexToBytes(hash) + ); + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + + var curvePt = curve.getG().multiply(privateKeyBigInt); + var x = curvePt.getX().toBigInteger(); + var y = curvePt.getY().toBigInteger(); + + var publicKeyBytes = EllipticCurve.integerToBytes(x, 32); + publicKeyBytes = publicKeyBytes.concat( + EllipticCurve.integerToBytes(y, 32) + ); + publicKeyBytes.unshift(0x04); + + if (bitjs.compressed == true) { + var publicKeyBytesCompressed = EllipticCurve.integerToBytes(x, 32); + if (y.isEven()) { + publicKeyBytesCompressed.unshift(0x02); + } else { + publicKeyBytesCompressed.unshift(0x03); + } + return Crypto.util.bytesToHex(publicKeyBytesCompressed); + } else { + return Crypto.util.bytesToHex(publicKeyBytes); + } + }; + + /* provide a public key and return address */ + bitjs.pubkey2address = function (h, byte) { + var r = ripemd160( + Crypto.SHA256(Crypto.util.hexToBytes(h), { + asBytes: true, + }) + ); + r.unshift(byte || bitjs.pub); + var hash = Crypto.SHA256( + Crypto.SHA256(r, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var checksum = hash.slice(0, 4); + return B58.encode(r.concat(checksum)); + }; + + bitjs.transaction = function () { + var btrx = {}; + btrx.version = 2; //flochange look at this version + btrx.inputs = []; + btrx.outputs = []; + btrx.locktime = 0; + btrx.floData = ""; //flochange .. look at this + + btrx.addinput = function (txid, index, scriptPubKey, sequence) { + var o = {}; + o.outpoint = { + hash: txid, + index: index, + }; + //o.script = []; Signature and Public Key should be added after singning + o.script = Crypto.util.hexToBytes(scriptPubKey); //push previous output pubkey script + o.sequence = sequence || (btrx.locktime == 0 ? 4294967295 : 0); + return this.inputs.push(o); + }; + + btrx.addoutput = function (address, value) { + var o = {}; + var buf = []; + var addrDecoded = btrx.addressDecode(address); + o.value = new BigInteger("" + Math.round(value * 1 * 1e8), 10); + buf.push(118); //OP_DUP + buf.push(169); //OP_HASH160 + buf.push(addrDecoded.length); + buf = buf.concat(addrDecoded); // address in bytes + buf.push(136); //OP_EQUALVERIFY + buf.push(172); // OP_CHECKSIG + o.script = buf; + return this.outputs.push(o); + }; + + btrx.addflodata = function (txcomments) { + // flochange - this whole function needs to be done + this.floData = txcomments; + return this.floData; //flochange .. returning the txcomments -- check if the function return will assign + }; + + // Only standard addresses + btrx.addressDecode = function (address) { + var bytes = B58.decode(address); + var front = bytes.slice(0, bytes.length - 4); + var back = bytes.slice(bytes.length - 4); + var checksum = Crypto.SHA256( + Crypto.SHA256(front, { + asBytes: true, + }), + { + asBytes: true, + } + ).slice(0, 4); + if (checksum + "" == back + "") { + return front.slice(1); + } + }; + + /* generate the transaction hash to sign from a transaction input */ + btrx.transactionHash = function (index, sigHashType) { + var clone = bitjs.clone(this); + var shType = sigHashType || 1; + + /* black out all other ins, except this one */ + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].script = []; + } + } + + if (clone.inputs && clone.inputs[index]) { + /* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG + and https://bitcoin.org/en/developer-guide#signature-hash-type */ + + if (shType == 1) { + //SIGHASH_ALL 0x01 + } else if (shType == 2) { + //SIGHASH_NONE 0x02 + clone.outputs = []; + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + } else if (shType == 3) { + //SIGHASH_SINGLE 0x03 + clone.outputs.length = index + 1; + + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + + for (var i = 0; i < clone.inputs.length; i++) { + if (index != i) { + clone.inputs[i].sequence = 0; + } + } + } else if (shType >= 128) { + //SIGHASH_ANYONECANPAY 0x80 + clone.inputs = [clone.inputs[index]]; + + if (shType == 129) { + // SIGHASH_ALL + SIGHASH_ANYONECANPAY + } else if (shType == 130) { + // SIGHASH_NONE + SIGHASH_ANYONECANPAY + clone.outputs = []; + } else if (shType == 131) { + // SIGHASH_SINGLE + SIGHASH_ANYONECANPAY + clone.outputs.length = index + 1; + for (var i = 0; i < index; i++) { + clone.outputs[i].value = -1; + clone.outputs[i].script = []; + } + } + } + + var buffer = Crypto.util.hexToBytes(clone.serialize()); + buffer = buffer.concat(bitjs.numToBytes(parseInt(shType), 4)); + var hash = Crypto.SHA256(buffer, { + asBytes: true, + }); + var r = Crypto.util.bytesToHex( + Crypto.SHA256(hash, { + asBytes: true, + }) + ); + return r; + } else { + return false; + } + }; + + /* generate a signature from a transaction hash */ + btrx.transactionSig = function (index, wif, sigHashType, txhash) { + function serializeSig(r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + } + + var shType = sigHashType || 1; + var hash = + txhash || + Crypto.util.hexToBytes(this.transactionHash(index, shType)); + + if (hash) { + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var key = bitjs.wif2privkey(wif); + var priv = BigInteger.fromByteArrayUnsigned( + Crypto.util.hexToBytes(key["privkey"]) + ); + var n = curve.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + var badrs = 0; + do { + var k = this.deterministicK(wif, hash, badrs); + var G = curve.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + var s = k + .modInverse(n) + .multiply(e.add(priv.multiply(r))) + .mod(n); + badrs++; + } while ( + r.compareTo(BigInteger.ZERO) <= 0 || + s.compareTo(BigInteger.ZERO) <= 0 + ); + + // Force lower s values per BIP62 + var halfn = n.shiftRight(1); + if (s.compareTo(halfn) > 0) { + s = n.subtract(s); + } + + var sig = serializeSig(r, s); + sig.push(parseInt(shType, 10)); + + return Crypto.util.bytesToHex(sig); + } else { + return false; + } + }; + + // https://tools.ietf.org/html/rfc6979#section-3.2 + btrx.deterministicK = function (wif, hash, badrs) { + // if r or s were invalid when this function was used in signing, + // we do not want to actually compute r, s here for efficiency, so, + // we can increment badrs. explained at end of RFC 6979 section 3.2 + + // wif is b58check encoded wif privkey. + // hash is byte array of transaction digest. + // badrs is used only if the k resulted in bad r or s. + + // some necessary things out of the way for clarity. + badrs = badrs || 0; + var key = bitjs.wif2privkey(wif); + var x = Crypto.util.hexToBytes(key["privkey"]); + var curve = EllipticCurve.getSECCurveByName("secp256k1"); + var N = curve.getN(); + + // Step: a + // hash is a byteArray of the message digest. so h1 == hash in our case + + // Step: b + var v = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + ]; + + // Step: c + var k = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + // Step: d + k = Crypto.HMAC( + Crypto.SHA256, + v.concat([0]).concat(x).concat(hash), + k, + { + asBytes: true, + } + ); + + // Step: e + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + + // Step: f + k = Crypto.HMAC( + Crypto.SHA256, + v.concat([1]).concat(x).concat(hash), + k, + { + asBytes: true, + } + ); + + // Step: g + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + + // Step: h1 + var T = []; + + // Step: h2 (since we know tlen = qlen, just copy v to T.) + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + T = v; + + // Step: h3 + var KBigInt = BigInteger.fromByteArrayUnsigned(T); + + // loop if KBigInt is not in the range of [1, N-1] or if badrs needs incrementing. + var i = 0; + while ( + KBigInt.compareTo(N) >= 0 || + KBigInt.compareTo(BigInteger.ZERO) <= 0 || + i < badrs + ) { + k = Crypto.HMAC(Crypto.SHA256, v.concat([0]), k, { + asBytes: true, + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + v = Crypto.HMAC(Crypto.SHA256, v, k, { + asBytes: true, + }); + T = v; + KBigInt = BigInteger.fromByteArrayUnsigned(T); + i++; + } + + return KBigInt; + }; + + /* sign a "standard" input */ + btrx.signinput = function (index, wif, sigHashType) { + var key = bitjs.wif2pubkey(wif); + var shType = sigHashType || 1; + var signature = this.transactionSig(index, wif, shType); + var buf = []; + var sigBytes = Crypto.util.hexToBytes(signature); + buf.push(sigBytes.length); + buf = buf.concat(sigBytes); + var pubKeyBytes = Crypto.util.hexToBytes(key["pubkey"]); + buf.push(pubKeyBytes.length); + buf = buf.concat(pubKeyBytes); + this.inputs[index].script = buf; + return true; + }; + + /* sign inputs */ + btrx.sign = function (wif, sigHashType) { + var shType = sigHashType || 1; + for (var i = 0; i < this.inputs.length; i++) { + this.signinput(i, wif, shType); + } + return this.serialize(); + }; + + /* serialize a transaction */ + btrx.serialize = function () { + var buffer = []; + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.version), 4)); + + buffer = buffer.concat(bitjs.numToVarInt(this.inputs.length)); + for (var i = 0; i < this.inputs.length; i++) { + var txin = this.inputs[i]; + buffer = buffer.concat( + Crypto.util.hexToBytes(txin.outpoint.hash).reverse() + ); + buffer = buffer.concat( + bitjs.numToBytes(parseInt(txin.outpoint.index), 4) + ); + var scriptBytes = txin.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + buffer = buffer.concat( + bitjs.numToBytes(parseInt(txin.sequence), 4) + ); + } + buffer = buffer.concat(bitjs.numToVarInt(this.outputs.length)); + + for (var i = 0; i < this.outputs.length; i++) { + var txout = this.outputs[i]; + buffer = buffer.concat(bitjs.numToBytes(txout.value, 8)); + var scriptBytes = txout.script; + buffer = buffer.concat(bitjs.numToVarInt(scriptBytes.length)); + buffer = buffer.concat(scriptBytes); + } + + buffer = buffer.concat(bitjs.numToBytes(parseInt(this.locktime), 4)); + flohex = ascii_to_hexa(this.floData); + floDataCount = this.floData.length; + + //flochange -- creating unique data character count logic for floData. This string is prefixed before actual floData string in Raw Transaction + if (floDataCount <= 16) { + floDataCountString = floDataCount.toString(16); + floDataCountString = "0" + floDataCountString; + } else if (floDataCount < 253) { + floDataCountString = floDataCount.toString(16); + } else if (floDataCount <= 1023) { + floDataCountAdjusted = floDataCount - 253 + parseInt("0xfd00fd"); + floDataCountStringAdjusted = floDataCountAdjusted.toString(16); + floDataCountString = + floDataCountStringAdjusted.substr(0, 2) + + floDataCountStringAdjusted.substr(4, 2) + + floDataCountStringAdjusted.substr(2, 2); + } else { + floDataCountString = "Character Limit Exceeded"; + } + + return Crypto.util.bytesToHex(buffer) + floDataCountString + flohex; // flochange -- Addition of floDataCountString and floData in serialization + }; + + return btrx; + }; + + bitjs.numToBytes = function (num, bytes) { + if (typeof bytes === "undefined") bytes = 8; + if (bytes == 0) { + return []; + } else if (num == -1) { + return Crypto.util.hexToBytes("ffffffffffffffff"); + } else { + return [num % 256].concat( + bitjs.numToBytes(Math.floor(num / 256), bytes - 1) + ); + } + }; + + bitjs.numToByteArray = function (num) { + if (num <= 256) { + return [num]; + } else { + return [num % 256].concat( + bitjs.numToByteArray(Math.floor(num / 256)) + ); + } + }; + + bitjs.numToVarInt = function (num) { + if (num < 253) { + return [num]; + } else if (num < 65536) { + return [253].concat(bitjs.numToBytes(num, 2)); + } else if (num < 4294967296) { + return [254].concat(bitjs.numToBytes(num, 4)); + } else { + return [255].concat(bitjs.numToBytes(num, 8)); + } + }; + + bitjs.bytesToNum = function (bytes) { + if (bytes.length == 0) return 0; + else return bytes[0] + 256 * bitjs.bytesToNum(bytes.slice(1)); + }; + + /* clone an object */ + bitjs.clone = function (obj) { + if (obj == null || typeof obj != "object") return obj; + var temp = new obj.constructor(); + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + temp[key] = bitjs.clone(obj[key]); + } + } + return temp; + }; + + var B58 = (bitjs.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function (input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(""); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function (input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add( + BigInteger.valueOf(alphaIndex).multiply( + B58.base.pow(input.length - 1 - i) + ) + ); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + }, + }); + return bitjs; + })(); + + /* + Copyright (c) 2011 Stefan Thomas + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/1a7fc9d063f864058809d06ef4542af40be3558f/src/bitcoin.js + (function (exports) { + var Bitcoin = exports; + })("object" === typeof module ? module.exports : (window.Bitcoin = {})); + + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js + (function (Bitcoin) { + Bitcoin.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function (input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(""); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function (input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add( + BigInteger.valueOf(alphaIndex).multiply( + B58.base.pow(input.length - 1 - i) + ) + ); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + }, + }; + + var B58 = Bitcoin.Base58; + })("undefined" != typeof Bitcoin ? Bitcoin : module.exports); + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js + Bitcoin.Address = function (bytes) { + if (floGlobals.blockchain == "FLO") this.version = 0x23; + // FLO mainnet public address + else if (floGlobals.blockchain == "FLO_TEST") this.version = 0x73; // FLO testnet public address + if ("string" == typeof bytes) { + bytes = Bitcoin.Address.decodeString(bytes, this.version); + } + this.hash = bytes; + }; + + Bitcoin.Address.networkVersion = 0x23; // (FLO mainnet 0x23, 35D), (Bitcoin Mainnet, 0x00, 0D) // *this has no effect * + + /** + * Serialize this object as a standard Bitcoin address. + * + * Returns the address as a base58-encoded string in the standardized format. + */ + Bitcoin.Address.prototype.toString = function () { + // Get a copy of the hash + var hash = this.hash.slice(0); + + // Version + hash.unshift(this.version); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + var bytes = hash.concat(checksum.slice(0, 4)); + return Bitcoin.Base58.encode(bytes); + }; + + Bitcoin.Address.prototype.getHashBase64 = function () { + return Crypto.util.bytesToBase64(this.hash); + }; + + /** + * Parse a Bitcoin address contained in a string. + */ + Bitcoin.Address.decodeString = function (string, version) { + var bytes = Bitcoin.Base58.decode(string); + var hash = bytes.slice(0, 21); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + + if ( + checksum[0] != bytes[21] || + checksum[1] != bytes[22] || + checksum[2] != bytes[23] || + checksum[3] != bytes[24] + ) { + throw "Checksum validation failed!"; + } + + if (version != hash.shift()) { + throw "Version " + hash.shift() + " not supported!"; + } + + return hash; + }; + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js + Bitcoin.ECDSA = (function () { + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + var rng = new SecureRandom(); + + var P_OVER_FOUR = null; + + function implShamirsTrick(P, k, Q, l) { + var m = Math.max(k.bitLength(), l.bitLength()); + var Z = P.add2D(Q); + var R = P.curve.getInfinity(); + + for (var i = m - 1; i >= 0; --i) { + R = R.twice2D(); + + R.z = BigInteger.ONE; + + if (k.testBit(i)) { + if (l.testBit(i)) { + R = R.add2D(Z); + } else { + R = R.add2D(P); + } + } else { + if (l.testBit(i)) { + R = R.add2D(Q); + } + } + } + + return R; + } + + var ECDSA = { + getBigRandom: function (limit) { + return new BigInteger(limit.bitLength(), rng) + .mod(limit.subtract(BigInteger.ONE)) + .add(BigInteger.ONE); + }, + sign: function (hash, priv) { + var d = priv; + var n = ecparams.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + + do { + var k = ECDSA.getBigRandom(n); + var G = ecparams.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + } while (r.compareTo(BigInteger.ZERO) <= 0); + + var s = k + .modInverse(n) + .multiply(e.add(d.multiply(r))) + .mod(n); + + return ECDSA.serializeSig(r, s); + }, + + verify: function (hash, sig, pubkey) { + var r, s; + if (Bitcoin.Util.isArray(sig)) { + var obj = ECDSA.parseSig(sig); + r = obj.r; + s = obj.s; + } else if ("object" === typeof sig && sig.r && sig.s) { + r = sig.r; + s = sig.s; + } else { + throw "Invalid value for signature"; + } + + var Q; + if (pubkey instanceof ec.PointFp) { + Q = pubkey; + } else if (Bitcoin.Util.isArray(pubkey)) { + Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey); + } else { + throw "Invalid format for pubkey value, must be byte array or ec.PointFp"; + } + var e = BigInteger.fromByteArrayUnsigned(hash); + + return ECDSA.verifyRaw(e, r, s, Q); + }, + + verifyRaw: function (e, r, s, Q) { + var n = ecparams.getN(); + var G = ecparams.getG(); + + if (r.compareTo(BigInteger.ONE) < 0 || r.compareTo(n) >= 0) + return false; + + if (s.compareTo(BigInteger.ONE) < 0 || s.compareTo(n) >= 0) + return false; + + var c = s.modInverse(n); + + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // TODO(!!!): For some reason Shamir's trick isn't working with + // signed message verification!? Probably an implementation + // error! + //var point = implShamirsTrick(G, u1, Q, u2); + var point = G.multiply(u1).add(Q.multiply(u2)); + + var v = point.getX().toBigInteger().mod(n); + + return v.equals(r); + }, + + /** + * Serialize a signature into DER format. + * + * Takes two BigIntegers representing r and s and returns a byte array. + */ + serializeSig: function (r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + }, + + /** + * Parses a byte array containing a DER-encoded signature. + * + * This function will return an object of the form: + * + * { + * r: BigInteger, + * s: BigInteger + * } + */ + parseSig: function (sig) { + var cursor; + if (sig[0] != 0x30) + throw new Error("Signature not a valid DERSequence"); + + cursor = 2; + if (sig[cursor] != 0x02) + throw new Error("First element in signature must be a DERInteger"); + var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + if (sig[cursor] != 0x02) + throw new Error("Second element in signature must be a DERInteger"); + var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + + //if (cursor != sig.length) + // throw new Error("Extra bytes in signature"); + + var r = BigInteger.fromByteArrayUnsigned(rBa); + var s = BigInteger.fromByteArrayUnsigned(sBa); + + return { + r: r, + s: s, + }; + }, + + parseSigCompact: function (sig) { + if (sig.length !== 65) { + throw "Signature has the wrong length"; + } + + // Signature is prefixed with a type byte storing three bits of + // information. + var i = sig[0] - 27; + if (i < 0 || i > 7) { + throw "Invalid signature type"; + } + + var n = ecparams.getN(); + var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n); + var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n); + + return { + r: r, + s: s, + i: i, + }; + }, + + /** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ + recoverPubKey: function (r, s, hash, i) { + // The recovery parameter i has two bits. + i = i & 3; + + // The less significant bit specifies whether the y coordinate + // of the compressed point is even or not. + var isYEven = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + var n = ecparams.getN(); + var G = ecparams.getG(); + var curve = ecparams.getCurve(); + var p = curve.getQ(); + var a = curve.getA().toBigInteger(); + var b = curve.getB().toBigInteger(); + + // We precalculate (p + 1) / 4 where p is if the field order + if (!P_OVER_FOUR) { + P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)); + } + + // 1.1 Compute x + var x = isSecondKey ? r.add(n) : r; + + // 1.3 Convert x to point + var alpha = x + .multiply(x) + .multiply(x) + .add(a.multiply(x)) + .add(b) + .mod(p); + var beta = alpha.modPow(P_OVER_FOUR, p); + + var xorOdd = beta.isEven() ? i % 2 : (i + 1) % 2; + // If beta is even, but y isn't or vice versa, then convert it, + // otherwise we're done and y == beta. + var y = (beta.isEven() ? !isYEven : isYEven) + ? beta + : p.subtract(beta); + + // 1.4 Check that nR is at infinity + var R = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y) + ); + R.validate(); + + // 1.5 Compute e from M + var e = BigInteger.fromByteArrayUnsigned(hash); + var eNeg = BigInteger.ZERO.subtract(e).mod(n); + + // 1.6 Compute Q = r^-1 (sR - eG) + var rInv = r.modInverse(n); + var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv); + + Q.validate(); + if (!ECDSA.verifyRaw(e, r, s, Q)) { + throw "Pubkey recovery unsuccessful"; + } + + var pubKey = new Bitcoin.ECKey(); + pubKey.pub = Q; + return pubKey; + }, + + /** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ + calcPubkeyRecoveryParam: function (address, r, s, hash) { + for (var i = 0; i < 4; i++) { + try { + var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i); + if (pubkey.getBitcoinAddress().toString() == address) { + return i; + } + } catch (e) {} + } + throw "Unable to find valid recovery factor"; + }, + }; + + return ECDSA; + })(); + Bitcoin.KeyPool = (function () { + var KeyPool = function () { + this.keyArray = []; + + this.push = function (item) { + if (item == null || item.priv == null) return; + var doAdd = true; + // prevent duplicates from being added to the array + for (var index in this.keyArray) { + var currentItem = this.keyArray[index]; + if ( + currentItem != null && + currentItem.priv != null && + item.getBitcoinAddress() == currentItem.getBitcoinAddress() + ) { + doAdd = false; + break; + } + } + if (doAdd) this.keyArray.push(item); + }; + + this.reset = function () { + this.keyArray = []; + }; + + this.getArray = function () { + // copy array + return this.keyArray.slice(0); + }; + + this.setArray = function (ka) { + this.keyArray = ka; + }; + + this.length = function () { + return this.keyArray.length; + }; + + this.toString = function () { + var keyPoolString = "# = " + this.length() + "\n"; + var pool = this.getArray(); + for (var index in pool) { + var item = pool[index]; + if ( + Bitcoin.Util.hasMethods(item, "getBitcoinAddress", "toString") + ) { + if (item != null) { + keyPoolString += + '"' + + item.getBitcoinAddress() + + '"' + + ', "' + + item.toString("wif") + + '"\n'; + } + } + } + + return keyPoolString; + }; + + return this; + }; + + return new KeyPool(); + })(); + + Bitcoin.Bip38Key = (function () { + var Bip38 = function (address, encryptedKey) { + this.address = address; + this.priv = encryptedKey; + }; + + Bip38.prototype.getBitcoinAddress = function () { + return this.address; + }; + + Bip38.prototype.toString = function () { + return this.priv; + }; + + return Bip38; + })(); + + //https://raw.github.com/pointbiz/bitcoinjs-lib/9b2f94a028a7bc9bed94e0722563e9ff1d8e8db8/src/eckey.js + Bitcoin.ECKey = (function () { + var ECDSA = Bitcoin.ECDSA; + var KeyPool = Bitcoin.KeyPool; + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + + var ECKey = function (input) { + if (!input) { + // Generate new key + var n = ecparams.getN(); + this.priv = ECDSA.getBigRandom(n); + } else if (input instanceof BigInteger) { + // Input is a private key value + this.priv = input; + } else if (Bitcoin.Util.isArray(input)) { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(input); + } else if ("string" == typeof input) { + var bytes = null; + try { + // This part is edited for FLO. FLO WIF are always compressed WIF. FLO WIF (private key) starts with R for mainnet and c for testnet. + if ( + (floGlobals.blockchain == "FLO" && + /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + input + )) || + (floGlobals.blockchain == "FLO_TEST" && + /^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + input + )) + ) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } + + /* + if (ECKey.isWalletImportFormat(input)) { + bytes = ECKey.decodeWalletImportFormat(input); + } else if (ECKey.isCompressedWalletImportFormat(input)) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isMiniFormat(input)) { + bytes = Crypto.SHA256(input, { asBytes: true }); + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } else if (ECKey.isBase64Format(input)) { + bytes = Crypto.util.base64ToBytes(input); + } + */ + } catch (exc1) { + this.setError(exc1); + } + + if (ECKey.isBase6Format(input)) { + this.priv = new BigInteger(input, 6); + } else if (bytes == null || bytes.length != 32) { + this.priv = null; + } else { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(bytes); + } + } + + this.compressed = + this.compressed == undefined + ? !!ECKey.compressByDefault + : this.compressed; + try { + // check not zero + if (this.priv != null && BigInteger.ZERO.compareTo(this.priv) == 0) + this.setError("Error: BigInteger equal to zero."); + // valid range [0x1, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140]) + var hexKeyRangeLimit = + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140"; + var rangeLimitBytes = Crypto.util.hexToBytes(hexKeyRangeLimit); + var limitBigInt = BigInteger.fromByteArrayUnsigned(rangeLimitBytes); + if (this.priv != null && limitBigInt.compareTo(this.priv) < 0) + this.setError("Error: BigInteger outside of curve range."); + + if (this.priv != null) { + KeyPool.push(this); + } + } catch (exc2) { + this.setError(exc2); + } + }; + + if (floGlobals.blockchain == "FLO") ECKey.privateKeyPrefix = 0xa3; + //(Bitcoin mainnet 0x80 testnet 0xEF) (FLO mainnet 0xA3 163 D) + else if (floGlobals.blockchain == "FLO_TEST") + ECKey.privateKeyPrefix = 0xef; //FLO testnet + + /** + * Whether public keys should be returned compressed by default. + */ + ECKey.compressByDefault = false; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setError = function (err) { + this.error = err; + this.priv = null; + return this; + }; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setCompressed = function (v) { + this.compressed = !!v; + if (this.pubPoint) this.pubPoint.compressed = this.compressed; + return this; + }; + + /* + * Return public key as a byte array in DER encoding + */ + ECKey.prototype.getPub = function () { + if (this.compressed) { + if (this.pubComp) return this.pubComp; + return (this.pubComp = this.getPubPoint().getEncoded(1)); + } else { + if (this.pubUncomp) return this.pubUncomp; + return (this.pubUncomp = this.getPubPoint().getEncoded(0)); + } + }; + + /** + * Return public point as ECPoint object. + */ + ECKey.prototype.getPubPoint = function () { + if (!this.pubPoint) { + this.pubPoint = ecparams.getG().multiply(this.priv); + this.pubPoint.compressed = this.compressed; + } + return this.pubPoint; + }; + + ECKey.prototype.getPubKeyHex = function () { + if (this.compressed) { + if (this.pubKeyHexComp) return this.pubKeyHexComp; + return (this.pubKeyHexComp = Crypto.util + .bytesToHex(this.getPub()) + .toString() + .toUpperCase()); + } else { + if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp; + return (this.pubKeyHexUncomp = Crypto.util + .bytesToHex(this.getPub()) + .toString() + .toUpperCase()); + } + }; + + /** + * Get the pubKeyHash for this key. + * + * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as + * a byte array. + */ + ECKey.prototype.getPubKeyHash = function () { + if (this.compressed) { + if (this.pubKeyHashComp) return this.pubKeyHashComp; + return (this.pubKeyHashComp = Bitcoin.Util.sha256ripe160( + this.getPub() + )); + } else { + if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp; + return (this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160( + this.getPub() + )); + } + }; + + ECKey.prototype.getBitcoinAddress = function () { + var hash = this.getPubKeyHash(); + var addr = new Bitcoin.Address(hash); + return addr.toString(); + }; + + /* + * Takes a public point as a hex string or byte array + */ + ECKey.prototype.setPub = function (pub) { + // byte array + if (Bitcoin.Util.isArray(pub)) { + pub = Crypto.util.bytesToHex(pub).toString().toUpperCase(); + } + var ecPoint = ecparams.getCurve().decodePointHex(pub); + this.setCompressed(ecPoint.compressed); + this.pubPoint = ecPoint; + return this; + }; + + // Sipa Private Key Wallet Import Format + ECKey.prototype.getBitcoinWalletImportFormat = function () { + var bytes = this.getBitcoinPrivateKeyByteArray(); + if (bytes == null) return ""; + bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte + if (this.compressed) bytes.push(0x01); // append 0x01 byte for compressed format + var checksum = Crypto.SHA256( + Crypto.SHA256(bytes, { + asBytes: true, + }), + { + asBytes: true, + } + ); + bytes = bytes.concat(checksum.slice(0, 4)); + var privWif = Bitcoin.Base58.encode(bytes); + return privWif; + }; + + // Private Key Hex Format + ECKey.prototype.getBitcoinHexFormat = function () { + return Crypto.util + .bytesToHex(this.getBitcoinPrivateKeyByteArray()) + .toString() + .toUpperCase(); + }; + + // Private Key Base64 Format + ECKey.prototype.getBitcoinBase64Format = function () { + return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray()); + }; + + ECKey.prototype.getBitcoinPrivateKeyByteArray = function () { + if (this.priv == null) return null; + // Get a copy of private key as a byte array + var bytes = this.priv.toByteArrayUnsigned(); + // zero pad if private key is less than 32 bytes + while (bytes.length < 32) bytes.unshift(0x00); + return bytes; + }; + + ECKey.prototype.toString = function (format) { + format = format || ""; + if ( + format.toString().toLowerCase() == "base64" || + format.toString().toLowerCase() == "b64" + ) { + return this.getBitcoinBase64Format(); + } + // Wallet Import Format + else if (format.toString().toLowerCase() == "wif") { + return this.getBitcoinWalletImportFormat(); + } else { + return this.getBitcoinHexFormat(); + } + }; + + ECKey.prototype.sign = function (hash) { + return ECDSA.sign(hash, this.priv); + }; + + ECKey.prototype.verify = function (hash, sig) { + return ECDSA.verify(hash, sig, this.getPub()); + }; + + /** + * Parse a wallet import format private key contained in a string. + */ + ECKey.decodeWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 33); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + if ( + checksum[0] != bytes[33] || + checksum[1] != bytes[34] || + checksum[2] != bytes[35] || + checksum[3] != bytes[36] + ) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + return hash; + }; + + /** + * Parse a compressed wallet import format private key contained in a string. + */ + ECKey.decodeCompressedWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 34); + var checksum = Crypto.SHA256( + Crypto.SHA256(hash, { + asBytes: true, + }), + { + asBytes: true, + } + ); + if ( + checksum[0] != bytes[34] || + checksum[1] != bytes[35] || + checksum[2] != bytes[36] || + checksum[3] != bytes[37] + ) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + if (version != ECKey.privateKeyPrefix) { + throw "Version " + version + " not supported!"; + } + hash.pop(); + return hash; + }; + + // 64 characters [0-9A-F] + ECKey.isHexFormat = function (key) { + key = key.toString(); + return /^[A-Fa-f0-9]{64}$/.test(key); + }; + + // 51 characters base58, always starts with a '5' + ECKey.isWalletImportFormat = function (key) { + key = key.toString(); + return ECKey.privateKeyPrefix == 0x80 + ? /^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test( + key + ) + : /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test( + key + ); + }; + + // 52 characters base58 + ECKey.isCompressedWalletImportFormat = function (key) { + key = key.toString(); + return ECKey.privateKeyPrefix == 0x80 + ? /^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + key + ) + : /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test( + key + ); + }; + + // 44 characters + ECKey.isBase64Format = function (key) { + key = key.toString(); + return /^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test( + key + ); + }; + + // 99 characters, 1=1, if using dice convert 6 to 0 + ECKey.isBase6Format = function (key) { + key = key.toString(); + return /^[012345]{99}$/.test(key); + }; + + // 22, 26 or 30 characters, always starts with an 'S' + ECKey.isMiniFormat = function (key) { + key = key.toString(); + var validChars22 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test( + key + ); + var validChars26 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test( + key + ); + var validChars30 = + /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test( + key + ); + var testBytes = Crypto.SHA256(key + "?", { + asBytes: true, + }); + + return ( + (testBytes[0] === 0x00 || testBytes[0] === 0x01) && + (validChars22 || validChars26 || validChars30) + ); + }; + + return ECKey; + })(); + //https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js + // Bitcoin utility functions + Bitcoin.Util = { + /** + * Cross-browser compatibility version of Array.isArray. + */ + isArray: + Array.isArray || + function (o) { + return Object.prototype.toString.call(o) === "[object Array]"; + }, + /** + * Create an array of a certain length filled with a specific value. + */ + makeFilledArray: function (len, val) { + var array = []; + var i = 0; + while (i < len) { + array[i++] = val; + } + return array; + }, + /** + * Turn an integer into a "var_int". + * + * "var_int" is a variable length integer used by Bitcoin's binary format. + * + * Returns a byte array. + */ + numToVarInt: function (i) { + if (i < 0xfd) { + // unsigned char + return [i]; + } else if (i <= 1 << 16) { + // unsigned short (LE) + return [0xfd, i >>> 8, i & 255]; + } else if (i <= 1 << 32) { + // unsigned int (LE) + return [0xfe].concat(Crypto.util.wordsToBytes([i])); + } else { + // unsigned long long (LE) + return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i])); + } + }, + /** + * Parse a Bitcoin value byte array, returning a BigInteger. + */ + valueToBigInt: function (valueBuffer) { + if (valueBuffer instanceof BigInteger) return valueBuffer; + + // Prepend zero byte to prevent interpretation as negative integer + return BigInteger.fromByteArrayUnsigned(valueBuffer); + }, + /** + * Format a Bitcoin value as a string. + * + * Takes a BigInteger or byte-array and returns that amount of Bitcoins in a + * nice standard formatting. + * + * Examples: + * 12.3555 + * 0.1234 + * 900.99998888 + * 34.00 + */ + formatValue: function (valueBuffer) { + var value = this.valueToBigInt(valueBuffer).toString(); + var integerPart = + value.length > 8 ? value.substr(0, value.length - 8) : "0"; + var decimalPart = + value.length > 8 ? value.substr(value.length - 8) : value; + while (decimalPart.length < 8) decimalPart = "0" + decimalPart; + decimalPart = decimalPart.replace(/0*$/, ""); + while (decimalPart.length < 2) decimalPart += "0"; + return integerPart + "." + decimalPart; + }, + /** + * Parse a floating point string as a Bitcoin value. + * + * Keep in mind that parsing user input is messy. You should always display + * the parsed value back to the user to make sure we understood his input + * correctly. + */ + parseValue: function (valueString) { + // TODO: Detect other number formats (e.g. comma as decimal separator) + var valueComp = valueString.split("."); + var integralPart = valueComp[0]; + var fractionalPart = valueComp[1] || "0"; + while (fractionalPart.length < 8) fractionalPart += "0"; + fractionalPart = fractionalPart.replace(/^0+/g, ""); + var value = BigInteger.valueOf(parseInt(integralPart)); + value = value.multiply(BigInteger.valueOf(100000000)); + value = value.add(BigInteger.valueOf(parseInt(fractionalPart))); + return value; + }, + /** + * Calculate RIPEMD160(SHA256(data)). + * + * Takes an arbitrary byte array as inputs and returns the hash as a byte + * array. + */ + sha256ripe160: function (data) { + return ripemd160( + Crypto.SHA256(data, { + asBytes: true, + }), + { + asBytes: true, + } + ); + }, + // double sha256 + dsha256: function (data) { + return Crypto.SHA256( + Crypto.SHA256(data, { + asBytes: true, + }), + { + asBytes: true, + } + ); + }, + // duck typing method + hasMethods: function (obj /*, method list as strings */) { + var i = 1, + methodName; + while ((methodName = arguments[i++])) { + if (typeof obj[methodName] != "function") { + return false; + } + } + return true; + }, + }; + + (function (ellipticCurveType) { + //Defining Elliptic Encryption Object + var ellipticEncryption = (window.ellipticCurveEncryption = + function () {}); + + ellipticEncryption.rng = new SecureRandom(); + + ellipticEncryption.getCurveParameters = function (curveName) { + //Default is secp256k1 + curveName = typeof curveName !== "undefined" ? curveName : "secp256k1"; + + var c = EllipticCurve.getSECCurveByName(curveName); + var curveDetails = { + Q: "", + A: "", + B: "", + GX: "", + GY: "", + N: "", + }; + + curveDetails.Q = c.getCurve().getQ().toString(); + curveDetails.A = c.getCurve().getA().toBigInteger().toString(); + curveDetails.B = c.getCurve().getB().toBigInteger().toString(); + curveDetails.GX = c.getG().getX().toBigInteger().toString(); + curveDetails.GY = c.getG().getY().toBigInteger().toString(); + curveDetails.N = c.getN().toString(); + + return curveDetails; + }; + + ellipticEncryption.selectedCurve = + ellipticEncryption.getCurveParameters(ellipticCurveType); + + ellipticEncryption.get_curve = function () { + return new EllipticCurve.CurveFp( + new BigInteger(this.selectedCurve.Q), + new BigInteger(this.selectedCurve.A), + new BigInteger(this.selectedCurve.B) + ); + }; + + ellipticEncryption.get_G = function (curve) { + return new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(this.selectedCurve.GX)), + curve.fromBigInteger(new BigInteger(this.selectedCurve.GY)) + ); + }; + + ellipticEncryption.pick_rand = function () { + var n = new BigInteger(this.selectedCurve.N); + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(n.bitLength(), this.rng); + return r.mod(n1).add(BigInteger.ONE); + }; + + ellipticEncryption.senderRandom = function () { + var r = this.pick_rand(); + return r.toString(); + }; + + ellipticEncryption.receiverRandom = function () { + //This is receivers private key. For now we will use random. CHANGE IT LATER + var r = this.pick_rand(); + return r.toString(); + }; + + ellipticEncryption.senderPublicString = function (senderPrivateKey) { + var senderKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(senderPrivateKey); + var P = G.multiply(a); + senderKeyECData.XValuePublicString = P.getX().toBigInteger().toString(); + senderKeyECData.YValuePublicString = P.getY().toBigInteger().toString(); + + return senderKeyECData; + }; + + //In real life ellipticEncryption.receiverPublicString is the public key of the receiver. + //you don't have to run receiverRandom and the bottom function + ellipticEncryption.receiverPublicString = function (receiverPublicKey) { + var receiverKeyECData = {}; + + var curve = this.get_curve(); + var G = this.get_G(curve); + var a = new BigInteger(receiverPublicKey); + var P = G.multiply(a); + receiverKeyECData.XValuePublicString = P.getX() + .toBigInteger() + .toString(); + receiverKeyECData.YValuePublicString = P.getY() + .toBigInteger() + .toString(); + + return receiverKeyECData; + }; + + ellipticEncryption.senderSharedKeyDerivation = function ( + receiverPublicStringXValue, + receiverPublicStringYValue, + senderPrivateKey + ) { + var senderDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(receiverPublicStringXValue)), + curve.fromBigInteger(new BigInteger(receiverPublicStringYValue)) + ); + var a = new BigInteger(senderPrivateKey); + var S = P.multiply(a); + + senderDerivedKey.XValue = S.getX().toBigInteger().toString(); + senderDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return senderDerivedKey; + }; + + ellipticEncryption.receiverSharedKeyDerivation = function ( + senderPublicStringXValue, + senderPublicStringYValue, + receiverPrivateKey + ) { + var receiverDerivedKey = {}; + var curve = this.get_curve(); + var P = new EllipticCurve.PointFp( + curve, + curve.fromBigInteger(new BigInteger(senderPublicStringXValue)), + curve.fromBigInteger(new BigInteger(senderPublicStringYValue)) + ); + var a = new BigInteger(receiverPrivateKey); + var S = P.multiply(a); + + receiverDerivedKey.XValue = S.getX().toBigInteger().toString(); + receiverDerivedKey.YValue = S.getY().toBigInteger().toString(); + + return receiverDerivedKey; + }; + })("secp256k1"); + + // secrets.js - by Alexander Stetsyuk - released under MIT License + (function (exports, global) { + var defaults = { + bits: 8, // default number of bits + radix: 16, // work with HEX by default + minBits: 3, + maxBits: 20, // this permits 1,048,575 shares, though going this high is NOT recommended in JS! + + bytesPerChar: 2, + maxBytesPerChar: 6, // Math.pow(256,7) > Math.pow(2,53) + + // Primitive polynomials (in decimal form) for Galois Fields GF(2^n), for 2 <= n <= 30 + // The index of each term in the array corresponds to the n for that polynomial + // i.e. to get the polynomial for n=16, use primitivePolynomials[16] + primitivePolynomials: [ + null, + null, + 1, + 3, + 3, + 5, + 3, + 3, + 29, + 17, + 9, + 5, + 83, + 27, + 43, + 3, + 45, + 9, + 39, + 39, + 9, + 5, + 3, + 33, + 27, + 9, + 71, + 39, + 9, + 5, + 83, + ], + + // warning for insecure PRNG + warning: + "WARNING:\nA secure random number generator was not found.\nUsing Math.random(), which is NOT cryptographically strong!", + }; + + // Protected settings object + var config = {}; + + /** @expose **/ + exports.getConfig = function () { + return { + bits: config.bits, + unsafePRNG: config.unsafePRNG, + }; + }; + + function init(bits) { + if ( + bits && + (typeof bits !== "number" || + bits % 1 !== 0 || + bits < defaults.minBits || + bits > defaults.maxBits) + ) { + throw new Error( + "Number of bits must be an integer between " + + defaults.minBits + + " and " + + defaults.maxBits + + ", inclusive." + ); + } + + config.radix = defaults.radix; + config.bits = bits || defaults.bits; + config.size = Math.pow(2, config.bits); + config.max = config.size - 1; + + // Construct the exp and log tables for multiplication. + var logs = [], + exps = [], + x = 1, + primitive = defaults.primitivePolynomials[config.bits]; + for (var i = 0; i < config.size; i++) { + exps[i] = x; + logs[x] = i; + x <<= 1; + if (x >= config.size) { + x ^= primitive; + x &= config.max; + } + } + + config.logs = logs; + config.exps = exps; + } + + /** @expose **/ + exports.init = init; + + function isInited() { + if ( + !config.bits || + !config.size || + !config.max || + !config.logs || + !config.exps || + config.logs.length !== config.size || + config.exps.length !== config.size + ) { + return false; + } + return true; + } + + // Returns a pseudo-random number generator of the form function(bits){} + // which should output a random string of 1's and 0's of length `bits` + function getRNG() { + var randomBits, crypto; + + function construct(bits, arr, radix, size) { + var str = "", + i = 0, + len = arr.length - 1; + while (i < len || str.length < bits) { + str += padLeft(parseInt(arr[i], radix).toString(2), size); + i++; + } + str = str.substr(-bits); + if ((str.match(/0/g) || []).length === str.length) { + // all zeros? + return null; + } else { + return str; + } + } + + // node.js crypto.randomBytes() + if ( + typeof require === "function" && + (crypto = require("crypto")) && + (randomBits = crypto["randomBytes"]) + ) { + return function (bits) { + var bytes = Math.ceil(bits / 8), + str = null; + + while (str === null) { + str = construct(bits, randomBits(bytes).toString("hex"), 16, 4); + } + return str; + }; + } + + // browsers with window.crypto.getRandomValues() + if ( + global["crypto"] && + typeof global["crypto"]["getRandomValues"] === "function" && + typeof global["Uint32Array"] === "function" + ) { + crypto = global["crypto"]; + return function (bits) { + var elems = Math.ceil(bits / 32), + str = null, + arr = new global["Uint32Array"](elems); + + while (str === null) { + crypto["getRandomValues"](arr); + str = construct(bits, arr, 10, 32); + } + + return str; + }; + } + + // A totally insecure RNG!!! (except in Safari) + // Will produce a warning every time it is called. + config.unsafePRNG = true; + warn(); + + var bitsPerNum = 32; + var max = Math.pow(2, bitsPerNum) - 1; + return function (bits) { + var elems = Math.ceil(bits / bitsPerNum); + var arr = [], + str = null; + while (str === null) { + for (var i = 0; i < elems; i++) { + arr[i] = Math.floor(Math.random() * max + 1); + } + str = construct(bits, arr, 10, bitsPerNum); + } + return str; + }; + } + + // Warn about using insecure rng. + // Called when Math.random() is being used. + function warn() { + global["console"]["warn"](defaults.warning); + if (typeof global["alert"] === "function" && config.alert) { + global["alert"](defaults.warning); + } + } + + // Set the PRNG to use. If no RNG function is supplied, pick a default using getRNG() + /** @expose **/ + exports.setRNG = function (rng, alert) { + if (!isInited()) { + this.init(); + } + config.unsafePRNG = false; + rng = rng || getRNG(); + + // test the RNG (5 times) + if ( + typeof rng !== "function" || + typeof rng(config.bits) !== "string" || + !parseInt(rng(config.bits), 2) || + rng(config.bits).length > config.bits || + rng(config.bits).length < config.bits + ) { + throw new Error( + "Random number generator is invalid. Supply an RNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's." + ); + } else { + config.rng = rng; + } + config.alert = !!alert; + + return !!config.unsafePRNG; + }; + + function isSetRNG() { + return typeof config.rng === "function"; + } + + // Generates a random bits-length number string using the PRNG + /** @expose **/ + exports.random = function (bits) { + if (!isSetRNG()) { + this.setRNG(); + } + + if (typeof bits !== "number" || bits % 1 !== 0 || bits < 2) { + throw new Error("Number of bits must be an integer greater than 1."); + } + + if (config.unsafePRNG) { + warn(); + } + return bin2hex(config.rng(bits)); + }; + + // Divides a `secret` number String str expressed in radix `inputRadix` (optional, default 16) + // into `numShares` shares, each expressed in radix `outputRadix` (optional, default to `inputRadix`), + // requiring `threshold` number of shares to reconstruct the secret. + // Optionally, zero-pads the secret to a length that is a multiple of padLength before sharing. + /** @expose **/ + exports.share = function ( + secret, + numShares, + threshold, + padLength, + withoutPrefix + ) { + if (!isInited()) { + this.init(); + } + if (!isSetRNG()) { + this.setRNG(); + } + + padLength = padLength || 0; + + if (typeof secret !== "string") { + throw new Error("Secret must be a string."); + } + if ( + typeof numShares !== "number" || + numShares % 1 !== 0 || + numShares < 2 + ) { + throw new Error( + "Number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive." + ); + } + if (numShares > config.max) { + var neededBits = Math.ceil(Math.log(numShares + 1) / Math.LN2); + throw new Error( + "Number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive. To create " + + numShares + + " shares, use at least " + + neededBits + + " bits." + ); + } + if ( + typeof threshold !== "number" || + threshold % 1 !== 0 || + threshold < 2 + ) { + throw new Error( + "Threshold number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive." + ); + } + if (threshold > config.max) { + var neededBits = Math.ceil(Math.log(threshold + 1) / Math.LN2); + throw new Error( + "Threshold number of shares must be an integer between 2 and 2^bits-1 (" + + config.max + + "), inclusive. To use a threshold of " + + threshold + + ", use at least " + + neededBits + + " bits." + ); + } + if (typeof padLength !== "number" || padLength % 1 !== 0) { + throw new Error("Zero-pad length must be an integer greater than 1."); + } + + if (config.unsafePRNG) { + warn(); + } + + secret = "1" + hex2bin(secret); // append a 1 so that we can preserve the correct number of leading zeros in our secret + secret = split(secret, padLength); + var x = new Array(numShares), + y = new Array(numShares); + for (var i = 0, len = secret.length; i < len; i++) { + var subShares = this._getShares(secret[i], numShares, threshold); + for (var j = 0; j < numShares; j++) { + x[j] = x[j] || subShares[j].x.toString(config.radix); + y[j] = padLeft(subShares[j].y.toString(2)) + (y[j] ? y[j] : ""); + } + } + var padding = config.max.toString(config.radix).length; + if (withoutPrefix) { + for (var i = 0; i < numShares; i++) { + x[i] = bin2hex(y[i]); + } + } else { + for (var i = 0; i < numShares; i++) { + x[i] = + config.bits.toString(36).toUpperCase() + + padLeft(x[i], padding) + + bin2hex(y[i]); + } + } + + return x; + }; + + // This is the basic polynomial generation and evaluation function + // for a `config.bits`-length secret (NOT an arbitrary length) + // Note: no error-checking at this stage! If `secrets` is NOT + // a NUMBER less than 2^bits-1, the output will be incorrect! + /** @expose **/ + exports._getShares = function (secret, numShares, threshold) { + var shares = []; + var coeffs = [secret]; + + for (var i = 1; i < threshold; i++) { + coeffs[i] = parseInt(config.rng(config.bits), 2); + } + for (var i = 1, len = numShares + 1; i < len; i++) { + shares[i - 1] = { + x: i, + y: horner(i, coeffs), + }; + } + return shares; + }; + + // Polynomial evaluation at `x` using Horner's Method + // TODO: this can possibly be sped up using other methods + // NOTE: fx=fx * x + coeff[i] -> exp(log(fx) + log(x)) + coeff[i], + // so if fx===0, just set fx to coeff[i] because + // using the exp/log form will result in incorrect value + function horner(x, coeffs) { + var logx = config.logs[x]; + var fx = 0; + for (var i = coeffs.length - 1; i >= 0; i--) { + if (fx === 0) { + fx = coeffs[i]; + continue; + } + fx = config.exps[(logx + config.logs[fx]) % config.max] ^ coeffs[i]; + } + return fx; + } + + function inArray(arr, val) { + for (var i = 0, len = arr.length; i < len; i++) { + if (arr[i] === val) { + return true; + } + } + return false; + } + + function processShare(share) { + var bits = parseInt(share[0], 36); + if ( + bits && + (typeof bits !== "number" || + bits % 1 !== 0 || + bits < defaults.minBits || + bits > defaults.maxBits) + ) { + throw new Error( + "Number of bits must be an integer between " + + defaults.minBits + + " and " + + defaults.maxBits + + ", inclusive." + ); + } + + var max = Math.pow(2, bits) - 1; + var idLength = max.toString(config.radix).length; + + var id = parseInt(share.substr(1, idLength), config.radix); + if (typeof id !== "number" || id % 1 !== 0 || id < 1 || id > max) { + throw new Error( + "Share id must be an integer between 1 and " + + config.max + + ", inclusive." + ); + } + share = share.substr(idLength + 1); + if (!share.length) { + throw new Error("Invalid share: zero-length share."); + } + return { + bits: bits, + id: id, + value: share, + }; + } + + /** @expose **/ + exports._processShare = processShare; + + // Protected method that evaluates the Lagrange interpolation + // polynomial at x=`at` for individual config.bits-length + // segments of each share in the `shares` Array. + // Each share is expressed in base `inputRadix`. The output + // is expressed in base `outputRadix' + function combine(at, shares) { + var setBits, + share, + x = [], + y = [], + result = "", + idx; + + for (var i = 0, len = shares.length; i < len; i++) { + share = processShare(shares[i]); + if (typeof setBits === "undefined") { + setBits = share["bits"]; + } else if (share["bits"] !== setBits) { + throw new Error("Mismatched shares: Different bit settings."); + } + + if (config.bits !== setBits) { + init(setBits); + } + + if (inArray(x, share["id"])) { + // repeated x value? + continue; + } + + idx = x.push(share["id"]) - 1; + share = split(hex2bin(share["value"])); + for (var j = 0, len2 = share.length; j < len2; j++) { + y[j] = y[j] || []; + y[j][idx] = share[j]; + } + } + + for (var i = 0, len = y.length; i < len; i++) { + result = padLeft(lagrange(at, x, y[i]).toString(2)) + result; + } + + if (at === 0) { + // reconstructing the secret + var idx = result.indexOf("1"); //find the first 1 + return bin2hex(result.slice(idx + 1)); + } else { + // generating a new share + return bin2hex(result); + } + } + + // Combine `shares` Array into the original secret + /** @expose **/ + exports.combine = function (shares) { + return combine(0, shares); + }; + + // Generate a new share with id `id` (a number between 1 and 2^bits-1) + // `id` can be a Number or a String in the default radix (16) + /** @expose **/ + exports.newShare = function (id, shares) { + if (typeof id === "string") { + id = parseInt(id, config.radix); + } + + var share = processShare(shares[0]); + var max = Math.pow(2, share["bits"]) - 1; + + if (typeof id !== "number" || id % 1 !== 0 || id < 1 || id > max) { + throw new Error( + "Share id must be an integer between 1 and " + + config.max + + ", inclusive." + ); + } + + var padding = max.toString(config.radix).length; + return ( + config.bits.toString(36).toUpperCase() + + padLeft(id.toString(config.radix), padding) + + combine(id, shares) + ); + }; + + // Evaluate the Lagrange interpolation polynomial at x = `at` + // using x and y Arrays that are of the same length, with + // corresponding elements constituting points on the polynomial. + function lagrange(at, x, y) { + var sum = 0, + product, + i, + j; + + for (var i = 0, len = x.length; i < len; i++) { + if (!y[i]) { + continue; + } + + product = config.logs[y[i]]; + for (var j = 0; j < len; j++) { + if (i === j) { + continue; + } + if (at === x[j]) { + // happens when computing a share that is in the list of shares used to compute it + product = -1; // fix for a zero product term, after which the sum should be sum^0 = sum, not sum^1 + break; + } + product = + (product + + config.logs[at ^ x[j]] - + config.logs[x[i] ^ x[j]] + + config.max) /* to make sure it's not negative */ % + config.max; + } + + sum = product === -1 ? sum : sum ^ config.exps[product]; // though exps[-1]= undefined and undefined ^ anything = anything in chrome, this behavior may not hold everywhere, so do the check + } + return sum; + } + + /** @expose **/ + exports._lagrange = lagrange; + + // Splits a number string `bits`-length segments, after first + // optionally zero-padding it to a length that is a multiple of `padLength. + // Returns array of integers (each less than 2^bits-1), with each element + // representing a `bits`-length segment of the input string from right to left, + // i.e. parts[0] represents the right-most `bits`-length segment of the input string. + function split(str, padLength) { + if (padLength) { + str = padLeft(str, padLength); + } + var parts = []; + for (var i = str.length; i > config.bits; i -= config.bits) { + parts.push(parseInt(str.slice(i - config.bits, i), 2)); + } + parts.push(parseInt(str.slice(0, i), 2)); + return parts; + } + + // Pads a string `str` with zeros on the left so that its length is a multiple of `bits` + function padLeft(str, bits) { + bits = bits || config.bits; + var missing = str.length % bits; + return (missing ? new Array(bits - missing + 1).join("0") : "") + str; + } + + function hex2bin(str) { + var bin = "", + num; + for (var i = str.length - 1; i >= 0; i--) { + num = parseInt(str[i], 16); + if (isNaN(num)) { + throw new Error("Invalid hex character."); + } + bin = padLeft(num.toString(2), 4) + bin; + } + return bin; + } + + function bin2hex(str) { + var hex = "", + num; + str = padLeft(str, 4); + for (var i = str.length; i >= 4; i -= 4) { + num = parseInt(str.slice(i - 4, i), 2); + if (isNaN(num)) { + throw new Error("Invalid binary character."); + } + hex = num.toString(16) + hex; + } + return hex; + } + + // Converts a given UTF16 character string to the HEX representation. + // Each character of the input string is represented by + // `bytesPerChar` bytes in the output string. + /** @expose **/ + exports.str2hex = function (str, bytesPerChar) { + if (typeof str !== "string") { + throw new Error("Input must be a character string."); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if ( + typeof bytesPerChar !== "number" || + bytesPerChar % 1 !== 0 || + bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar + ) { + throw new Error( + "Bytes per character must be an integer between 1 and " + + defaults.maxBytesPerChar + + ", inclusive." + ); + } + + var hexChars = 2 * bytesPerChar; + var max = Math.pow(16, hexChars) - 1; + var out = "", + num; + for (var i = 0, len = str.length; i < len; i++) { + num = str[i].charCodeAt(); + if (isNaN(num)) { + throw new Error("Invalid character: " + str[i]); + } else if (num > max) { + var neededBytes = Math.ceil(Math.log(num + 1) / Math.log(256)); + throw new Error( + "Invalid character code (" + + num + + "). Maximum allowable is 256^bytes-1 (" + + max + + "). To convert this character, use at least " + + neededBytes + + " bytes." + ); + } else { + out = padLeft(num.toString(16), hexChars) + out; + } + } + return out; + }; + + // Converts a given HEX number string to a UTF16 character string. + /** @expose **/ + exports.hex2str = function (str, bytesPerChar) { + if (typeof str !== "string") { + throw new Error("Input must be a hexadecimal string."); + } + bytesPerChar = bytesPerChar || defaults.bytesPerChar; + + if ( + typeof bytesPerChar !== "number" || + bytesPerChar % 1 !== 0 || + bytesPerChar < 1 || + bytesPerChar > defaults.maxBytesPerChar + ) { + throw new Error( + "Bytes per character must be an integer between 1 and " + + defaults.maxBytesPerChar + + ", inclusive." + ); + } + + var hexChars = 2 * bytesPerChar; + var out = ""; + str = padLeft(str, hexChars); + for (var i = 0, len = str.length; i < len; i += hexChars) { + out = + String.fromCharCode(parseInt(str.slice(i, i + hexChars), 16)) + out; + } + return out; + }; + + // by default, initialize without an RNG + exports.init(); + })( + typeof module !== "undefined" && module["exports"] + ? module["exports"] + : (window["shamirSecretShare"] = {}), + typeof global !== "undefined" ? global : window + ); + + //For diff base + /* + Functions available: + diff(originalObj, updatedObj) returns the difference of the original and updated objects + addedDiff(original, updatedObj) returns only the values added to the updated object + deletedDiff(original, updatedObj) returns only the values deleted in the updated object + updatedDiff(original, updatedObj) returns only the values that have been changed in the updated object + findDifference(original, updatedObj) returns an object with the added, deleted and updated differences + mergeRecurcive(original, diff) this will get you a new object that will merge all the changes between the old object and the new object + */ + (function () { + const isDate = (d) => d instanceof Date; + const isEmpty = (o) => Object.keys(o).length === 0; + const isObject = (o) => o != null && typeof o === "object"; + const properObject = (o) => + isObject(o) && !o.hasOwnProperty + ? { + ...o, + } + : o; + + const getLargerArray = (l, r) => (l.length > r.length ? l : r); + + const preserve = (diff, left, right) => { + if (!isObject(diff)) return diff; + + return Object.keys(diff).reduce((acc, key) => { + const leftArray = left[key]; + const rightArray = right[key]; + + if (Array.isArray(leftArray) && Array.isArray(rightArray)) { + const array = [...getLargerArray(leftArray, rightArray)]; + return { + ...acc, + [key]: array.reduce((acc2, item, index) => { + if (diff[key].hasOwnProperty(index)) { + acc2[index] = preserve( + diff[key][index], + leftArray[index], + rightArray[index] + ); // diff recurse and check for nested arrays + return acc2; + } + + delete acc2[index]; // no diff aka empty + return acc2; + }, array), + }; + } + + return { + ...acc, + [key]: diff[key], + }; + }, {}); + }; + + const updatedDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; + + if (!isObject(lhs) || !isObject(rhs)) return rhs; + + const l = properObject(lhs); + const r = properObject(rhs); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = updatedDiff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return acc; + }, {}); + }; + + const diff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + + const l = properObject(lhs); + const r = properObject(rhs); + + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) + ? acc + : { + ...acc, + [key]: null, + }; + }, {}); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) + return { + ...acc, + [key]: r[key], + }; // return added r key + + const difference = diff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; // return no diff + + return { + ...acc, + [key]: difference, + }; // return updated key + }, deletedValues); + }; + + const addedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + + const l = properObject(lhs); + const r = properObject(rhs); + + return Object.keys(r).reduce((acc, key) => { + if (l.hasOwnProperty(key)) { + const difference = addedDiff(l[key], r[key]); + + if (isObject(difference) && isEmpty(difference)) return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return { + ...acc, + [key]: r[key], + }; + }, {}); + }; + + const arrayDiff = (lhs, rhs) => { + if (lhs === rhs) return {}; // equal return no diff + + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs + + const l = properObject(lhs); + const r = properObject(rhs); + + const deletedValues = Object.keys(l).reduce((acc, key) => { + return r.hasOwnProperty(key) + ? acc + : { + ...acc, + [key]: null, + }; + }, {}); + + if (isDate(l) || isDate(r)) { + if (l.valueOf() == r.valueOf()) return {}; + return r; + } + + if (Array.isArray(r) && Array.isArray(l)) { + const deletedValues = l.reduce((acc, item, index) => { + return r.hasOwnProperty(index) + ? acc.concat(item) + : acc.concat(null); + }, []); + + return r.reduce((acc, rightItem, index) => { + if (!deletedValues.hasOwnProperty(index)) { + return acc.concat(rightItem); + } + + const leftItem = l[index]; + const difference = diff(rightItem, leftItem); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) { + delete acc[index]; + return acc; // return no diff + } + + return acc + .slice(0, index) + .concat(rightItem) + .concat(acc.slice(index + 1)); // return updated key + }, deletedValues); + } + + return Object.keys(r).reduce((acc, key) => { + if (!l.hasOwnProperty(key)) + return { + ...acc, + [key]: r[key], + }; // return added r key + + const difference = diff(l[key], r[key]); + + if ( + isObject(difference) && + isEmpty(difference) && + !isDate(difference) + ) + return acc; // return no diff + + return { + ...acc, + [key]: difference, + }; // return updated key + }, deletedValues); + }; + + const deletedDiff = (lhs, rhs) => { + if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {}; + + const l = properObject(lhs); + const r = properObject(rhs); + + return Object.keys(l).reduce((acc, key) => { + if (r.hasOwnProperty(key)) { + const difference = deletedDiff(l[key], r[key]); + + if (isObject(difference) && isEmpty(difference)) return acc; + + return { + ...acc, + [key]: difference, + }; + } + + return { + ...acc, + [key]: null, + }; + }, {}); + }; + + window.findDifference = (lhs, rhs) => ({ + added: addedDiff(lhs, rhs), + deleted: deletedDiff(lhs, rhs), + updated: updatedDiff(lhs, rhs), + }); + + const mergeRecursive = (obj1, obj2) => { + for (var p in obj2) { + try { + if (obj2[p].constructor == Object) { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } + // Property in destination object set; update its value. + else if (Ext.isArray(obj2[p])) { + // obj1[p] = []; + if (obj2[p].length < 1) { + obj1[p] = obj2[p]; + } else { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + } + } else { + obj1[p] = obj2[p]; + } + } catch (e) { + // Property in destination object not set; create it and set its value. + obj1[p] = obj2[p]; + } + } + return obj1; + }; + + /* + var test = { + foo : { + bar : { + baz : null + } + }, + bar : 1 + }; + cleanse(test); + + Rohit: Added a small fix for object being entered as Array*/ + + const cleanse = (obj) => { + Object.keys(obj).forEach((key) => { + var value = obj[key]; + if (typeof value === "object" && value !== null) { + // Recurse... + cleanse(value); + // ...and remove if now "empty" (NOTE: insert your definition of "empty" here) + if (!Object.keys(value).length) { + delete obj[key]; + } + } else if (value === null) { + // null, remove it + delete obj[key]; + } + }); + + if (obj.constructor.toString().indexOf("Array") != -1) { + obj = obj.filter(function (el) { + return el != null; + }); + } + + return obj; + }; + + /*obj is original object or array, diff is the output of findDifference */ + window.mergeDifference = (obj, diff) => { + if (Object.keys(diff.updated).length !== 0) + obj = mergeRecursive(obj, diff.updated); + if (Object.keys(diff.deleted).length !== 0) { + obj = mergeRecursive(obj, diff.deleted); + obj = cleanse(obj); + } + if (Object.keys(diff.added).length !== 0) + obj = mergeRecursive(obj, diff.added); + return obj; + }; + })(); + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RELIANCE - FUTURE GROUP DEAL AMAZON SENDS LEGAL NOTICE FOR BREACH OF CONTRACT.htm b/RELIANCE - FUTURE GROUP DEAL AMAZON SENDS LEGAL NOTICE FOR BREACH OF CONTRACT.htm index b3ac4cc..0883447 100644 --- a/RELIANCE - FUTURE GROUP DEAL AMAZON SENDS LEGAL NOTICE FOR BREACH OF CONTRACT.htm +++ b/RELIANCE - FUTURE GROUP DEAL AMAZON SENDS LEGAL NOTICE FOR BREACH OF CONTRACT.htm @@ -392,12 +392,7 @@ Then again, if the parties do not comply voluntarily to the decision made by SAI This can be a huge impact for the Future Group as they already lost about 7000 crores in the span of the first three to four months during COVID-19. Also, the company’s debt distress will be worsened now. It already suffered a huge amount of loss due to diversification too soon. -This deal has knocked hard on the Future Group and it might result in the closure of the group if the claims made by Amazon are proven true by the SEBI or Indian Courts.

- - Vote - - -
+This deal has knocked hard on the Future Group and it might result in the closure of the group if the claims made by Amazon are proven true by the SEBI or Indian Courts.

diff --git a/THE BLOCKS OF SUSTENANCE.html b/THE BLOCKS OF SUSTENANCE.html index ac4b3ca..054ac23 100644 --- a/THE BLOCKS OF SUSTENANCE.html +++ b/THE BLOCKS OF SUSTENANCE.html @@ -728,13 +728,6 @@ positive impact through a commitment to explore applications of self.

-
- - Vote - - -
@@ -812,2492 +805,2385 @@ sessionStorage.removeItem('z'); } - + Upvote + + + +

+ + + + + + + + + + + + + - - - + requestObjectData: function (keyPath) { + return new Promise((resolve, reject) => { + this.util + .requestData([floGlobals.application, "appObjects"].concat(keyPath)) + .then((result) => { + if (result[0]) resolve(result[1]); + else reject(result[1]); + }) + .catch((error) => reject(error)); + }); + }, + requestSubAdminList: function () { + return new Promise((resolve, reject) => { + this.util + .requestData([floGlobals.application, "subAdmins"]) + .then((result) => { + if (result[0]) resolve(result[1]); + else reject(result[1]); + }) + .catch((error) => reject(error)); + }); + }, + }; + + \ No newline at end of file diff --git a/THE MOST PROMISING YET LEAST KNOWN TECHNOLOGICAL DEVELOPMENTS TODAY (2020).htm b/THE MOST PROMISING YET LEAST KNOWN TECHNOLOGICAL DEVELOPMENTS TODAY (2020).htm index 050edf4..c7b9d52 100644 --- a/THE MOST PROMISING YET LEAST KNOWN TECHNOLOGICAL DEVELOPMENTS TODAY (2020).htm +++ b/THE MOST PROMISING YET LEAST KNOWN TECHNOLOGICAL DEVELOPMENTS TODAY (2020).htm @@ -411,12 +411,7 @@ These measurement instruments which utilize quantum states are present for quite A prevalent hurdle in quantum sensing is the dispute between isolating the sensitive quantum states from external disturbances consequently while being able to manipulate the quantum states and expose them to the physical quantity that can be measured. These sensors are theoretically proven to be far more helpful than normal sensors, but they are not commercially recognized for their high prices.   Some commercially accepted products of quantum sensors are atomic clocks and compact gravity meters. To enhance the accuracy of the atomic clocks, the researchers are now turning to atomic transitions at optical or even ultraviolet frequencies, and experimenting with single quantum systems. On the other hand, compact gravity meters are employed for detailed underground mappings like mineral prospecting, geophysical surveys, and seismology.  -The future impact of quantum sensing can be revolutionary in many scientific and commercial sectors. They are projected to enable autonomous driving, detection of minor particles of explosives and poisons, detailed underground mapping, medical advancements, and many more.

- - Vote - - -
+The future impact of quantum sensing can be revolutionary in many scientific and commercial sectors. They are projected to enable autonomous driving, detection of minor particles of explosives and poisons, detailed underground mapping, medical advancements, and many more.

diff --git a/TRUMP-BIDEN FIRST PRESIDENTIAL DEBATE 2020.htm b/TRUMP-BIDEN FIRST PRESIDENTIAL DEBATE 2020.htm index 68223be..7981060 100644 --- a/TRUMP-BIDEN FIRST PRESIDENTIAL DEBATE 2020.htm +++ b/TRUMP-BIDEN FIRST PRESIDENTIAL DEBATE 2020.htm @@ -435,12 +435,7 @@ But, if a path midway is  found, then debates should happen, not between just t By this, the level of discourse will not only improve, but there will be more talks about gender inequality,  climate changes etc. -In conclusion, we should have multiple structured debates between senior leaders across the parties with the topics known in the public forum beforehand mediated by an independent authority.

- - Vote - - -
+In conclusion, we should have multiple structured debates between senior leaders across the parties with the topics known in the public forum beforehand mediated by an independent authority.

diff --git a/UNCOMMON PETS AND THEIR STORIES!.html b/UNCOMMON PETS AND THEIR STORIES!.html index 9295c7d..f87ec62 100644 --- a/UNCOMMON PETS AND THEIR STORIES!.html +++ b/UNCOMMON PETS AND THEIR STORIES!.html @@ -284,12 +284,7 @@
John Boyko's alligators

John Boyko, a forty-two-year-old electrical contractor, became famous in New York City for rearing three alligators as his pets. The New York Times covered this story in 2003. It may seem uncommon to choose an alligator as a pet, but Boyko found it interesting, and hence in 1994 bought two alligators, Gertrude and Allie, out of curiosity. They also adopted a third gator from a veterinarian and named it Walley. People nicknamed Boyko “Gator Guy” because he had gators but no kids. The menageries spent their winters at Boyko's home in Bridgeport and summers at his mother's place in Shelton. The gators loved riding in Boyko’s convertible the cities, but sometimes became clamored for the front seat. However, people weren't so comfortable with the gators living in the city. Consequently, Bridgeport police raided Mr. Boyko's home after getting complaints from the neighbors. They confiscated the three gators and put them in the city zoo. Later, Boyko spent thousands of dollars in legal fees in trying to get them back. The Department of Environmental Protection rejected his request to keep the three alligators as pets and concluded that they could be a potential threat to other citizens. The local authorities gave him an option to either ship the gators to another state or donate them legally to the Beardsley Zoo. It was during this time that fortunately Betsy Gimbel, a pet lover, helped Boyko to keep his alligators on her property in Pennsylvania, where the laws allowed non-native menageries. Hence, Boyko relocated his gators to Pennsylvania. He drove there from Bridgeport once a week to look after the gators. Later, Gregg Dancho, the zoo director, appreciated Boyko for providing the gators a better home than the zoo. When Gimbel died in 2005, Boyko again struggled to shift the gators to another safe place. Boyko finally bought a home in East Stroudsburg, Poconos, for his reptilian pets. He set up the backyard with a 2,000-gallon tank for them, surrounded by a 6-foot tall stockyard fence. Later, he managed their expenses by having the gators appear in movies. Afterward, Boyko proudly acquired 11 gators, as some of them were either rescued or adopted. Boyko, as a father figure, continued to look after them as if they were his children.

Rex, the Nile monitor lizard

Ronald Huff, a forty-two-year-old soldier lived in Newark, Delaware. Huff was a passionate animal lover and had been fond of reptiles since childhood. During his visit to Africa, he came to know about Africa's longest lizard, the Nile lizard. He had always wanted to keep an exotic animal as a pet. The lizards cannot be acquired without a permit from the State Department of Animals. Since Huff was a soldier, he somehow managed to get the permit to keep a Nile monitor lizard as his pet. In 2001, Huff brought a Nile monitor lizard and named it Rex. Rex was 6 feet (1.83 m) long and weighed 25 pounds, had sharp teeth and jaws, and a muscular tail. Huff made Rex a big and elongated cell, but he usually unleashed the pet and allowed it to wander freely all over his house. Huff used to play and roam around his garden with Rex every day, and the neighbors and relatives knew about it. One of his neighbors, Maria, got skeptical when she noticed Ronald’s absence for a week. Out of suspicion, she called the police, and the cops arrived at Huff's house. They could hear a squeaking sound from inside the house. When the cops finally entered the house, they discovered Mr. Huff's body was half-eaten by the monitor lizard, and it was still feeding on his flesh. The lizard ate most of his body parts, including his legs, hands, and partially cleaved his neck. The cops recovered Huff's body and caged the lizard. To date, whenever the cops recall the incident, they get goosebumps because they had never witnessed such a terrifying incident in their lives.

Christian, the lion

A lion mother rejected her newborn cub at the Ilfracombe Zoo in Devon, UK. The zoo authorities sold the cub to Harrods department store in London to be used for publicity on Christmas Eve. Ace Bourse and John Rendall, two young travelers, bought the cub from the store and named it Christian. The cub lived with them in Chelsea, London. The cub adapted very well because of its sociable nature. Ace and John created a stable environment for Christian, by providing him the right food and a large basement to live in below the furniture shop where they worked. They looked after it as their child and every afternoon, they used to take Christian to a nearby garden for recreation. Christian grew up quickly, and within months he outgrew his environment. This concerned John and Ace, as the customers started getting scared of the growing lion, and they didn't have another space to move him. One day, Bill Travers, a film actor, came to the shop and found Christian to be charismatic. Hearing about the problems John and Ace were facing, Bill suggested that they contact a Kenyan wildlife conservationist who could rehabilitate Christian to a natural environment. When Christian arrived in Kenya, he faced many challenges, including a hostile environment and the presence of wild lions. He gradually overcame the obstacles thanks to his adaptive nature. A year later, when Ace and John came to meet Christian, he was strong and fully grown. YouTube featured their memorable reunion that got 100 million views. Their extraordinary story influences people to think deeply about the environment, wildlife issues, and animal welfare.

-
Gypsy, the Burmese python

Jaren Hare was a fourteen-year-old girl who lived in Florida with her parents. She was fascinated to see a small albino Burmese python in the flea market and decided to buy a corn-colored one with her pocket money. She named it Gypsy. Gypsy grew out to be an eight-foot-long snake. After a few years, Jaren was married and she had a baby named Shaiunna. Jaren had immense love for Gypsy. However, things started to get wrong when Jaren began ignoring it. The python used to stay in a terrarium covered by a cloth hooked by a safety pin. Jaren forgot to feed the python for days. Gypsy tried to get out of the tank several times to search for food. One night, the snake glided out of the tank and attacked her 2-years-old baby, Shaiunna. The python bit its face, hands, abdomen and strangled the baby to death. It was reported that Jaren was addicted to drugs and was soporific most of the time. Therefore, we saw how a baby lost its life because of the owner’s negligence. Hence, one should be cautious before petting dangerous exotic animals as the owner's behavior towards the pet plays a crucial role in understanding their needs.

- - Vote - - -
+
Gypsy, the Burmese python

Jaren Hare was a fourteen-year-old girl who lived in Florida with her parents. She was fascinated to see a small albino Burmese python in the flea market and decided to buy a corn-colored one with her pocket money. She named it Gypsy. Gypsy grew out to be an eight-foot-long snake. After a few years, Jaren was married and she had a baby named Shaiunna. Jaren had immense love for Gypsy. However, things started to get wrong when Jaren began ignoring it. The python used to stay in a terrarium covered by a cloth hooked by a safety pin. Jaren forgot to feed the python for days. Gypsy tried to get out of the tank several times to search for food. One night, the snake glided out of the tank and attacked her 2-years-old baby, Shaiunna. The python bit its face, hands, abdomen and strangled the baby to death. It was reported that Jaren was addicted to drugs and was soporific most of the time. Therefore, we saw how a baby lost its life because of the owner’s negligence. Hence, one should be cautious before petting dangerous exotic animals as the owner's behavior towards the pet plays a crucial role in understanding their needs.

diff --git a/WHAT DOES THE INDIAN ECONOMY NEED RIGHT NOW.htm b/WHAT DOES THE INDIAN ECONOMY NEED RIGHT NOW.htm index a932640..c3e6e99 100644 --- a/WHAT DOES THE INDIAN ECONOMY NEED RIGHT NOW.htm +++ b/WHAT DOES THE INDIAN ECONOMY NEED RIGHT NOW.htm @@ -604,12 +604,7 @@ The government can issue bonds to borrow money - It may be convenient for countr   -It might be controlled through money printed by the RBI - It directly depends on the taxation policy of the government and the income of individuals. Higher-income people help them to save more as compared to lower-income. In the long run, government spending must be controlled with low spending commitments and by remarkably reducing spending to sustainable levels.

- - Vote - - -
+It might be controlled through money printed by the RBI - It directly depends on the taxation policy of the government and the income of individuals. Higher-income people help them to save more as compared to lower-income. In the long run, government spending must be controlled with low spending commitments and by remarkably reducing spending to sustainable levels.

diff --git a/WILL INDIA- US PARTNERSHIP WORK UNDER JOE BIDEN.htm b/WILL INDIA- US PARTNERSHIP WORK UNDER JOE BIDEN.htm index 6a1e2be..9a6a79f 100644 --- a/WILL INDIA- US PARTNERSHIP WORK UNDER JOE BIDEN.htm +++ b/WILL INDIA- US PARTNERSHIP WORK UNDER JOE BIDEN.htm @@ -416,12 +416,7 @@ The United States and India have a long way to go in building a long-lasting, su   -Unfortunately, India isn't able to build such a reciprocal gesture. We are careful to not lose the forest for the trees. There's still plenty to be positive about in the U.S. - India relationship. Each country could also move

- - Vote - - -
+Unfortunately, India isn't able to build such a reciprocal gesture. We are careful to not lose the forest for the trees. There's still plenty to be positive about in the U.S. - India relationship. Each country could also move

diff --git a/WORLD'S FIRST FOUL AIR DEATH IN THE UK.htm b/WORLD'S FIRST FOUL AIR DEATH IN THE UK.htm index 4e38056..9397895 100644 --- a/WORLD'S FIRST FOUL AIR DEATH IN THE UK.htm +++ b/WORLD'S FIRST FOUL AIR DEATH IN THE UK.htm @@ -331,12 +331,7 @@ According to Dr. Maria Meira, Director of  WHO department of environment, clima breathe polluted Air on a daily basis. According to the most recent data released by State of Global Air 2019, Air Pollution is the fifth leading risk factor for mortality globally leaving behind the other well-known risk factors of death such as alcohol use, malnutrition, and physical inactivity. Air Pollution reduced the life expectancy by 1 year and 8 months. In 2017, on an average worldwide and around 3.6 billion people that is nearly a half of the total world's population were exposed to household air pollution. -Nevertheless, Death of Ella kissi- Debrah at the age of 9, Sparkle the foglamp on toxic quality of air. This could raise an important legal step and makes the  stronger point that the toxic air is being consumed by the people every day. WHO has summoned a global platform to reduce air pollution and its impact on health and climate. The organisation is also leading an Urban Health Initiative and is taking effective urban air pollution controlling actions. It is also spreading awareness among the people to the surging need for taking actions to curb the air pollution and its effect on climate and health.

- - Vote - - -
+Nevertheless, Death of Ella kissi- Debrah at the age of 9, Sparkle the foglamp on toxic quality of air. This could raise an important legal step and makes the  stronger point that the toxic air is being consumed by the people every day. WHO has summoned a global platform to reduce air pollution and its impact on health and climate. The organisation is also leading an Urban Health Initiative and is taking effective urban air pollution controlling actions. It is also spreading awareness among the people to the surging need for taking actions to curb the air pollution and its effect on climate and health.

diff --git a/WORLD'S LARGEST TRADE DEAL TO BE SIGNED WITHOUT INDIA.htm b/WORLD'S LARGEST TRADE DEAL TO BE SIGNED WITHOUT INDIA.htm index 897ec83..52f41a7 100644 --- a/WORLD'S LARGEST TRADE DEAL TO BE SIGNED WITHOUT INDIA.htm +++ b/WORLD'S LARGEST TRADE DEAL TO BE SIGNED WITHOUT INDIA.htm @@ -383,12 +383,7 @@ Trade balance with ASEAN FTA has worsened in thirteen out of twenty-one sectors, India’s trade deficit with the bloc has risen from $9 billion in the financial year 2005-06 to $83 billion in the Financial Year 2017-18. India has a trade deficit with as many as 11 RCEP countries and China is responsible for almost half of India’s trade deficit. China has grown  13% imports, while India has grown 26% of imports from China since 2004. This led to a widening gap of trade deficit. Since 2006, exports to RTA partners have increased by 13% which is almost the same trend as non-partner countries. -This trade asymmetry is mainly compounded by the nature of goods flow. India exports primary materials such as Iron ore, Cotton, and minerals whereas imports a wide variety of sophisticated products higher up in the value chain. India’s trade basket is not much diversified as compared to other Asian countries. Also, the utilization rate of RTAs by exporters of India is only between 5 -25%. This had implications for the domestic trade as well. Recently, Farmers from South India have argued that they can’t contend with spices and vegetable oil from Southeast Asian countries.

- - Vote - - -
+This trade asymmetry is mainly compounded by the nature of goods flow. India exports primary materials such as Iron ore, Cotton, and minerals whereas imports a wide variety of sophisticated products higher up in the value chain. India’s trade basket is not much diversified as compared to other Asian countries. Also, the utilization rate of RTAs by exporters of India is only between 5 -25%. This had implications for the domestic trade as well. Recently, Farmers from South India have argued that they can’t contend with spices and vegetable oil from Southeast Asian countries.

diff --git a/Walmart's Flipkart and IRFC prepare for an IPO in the US.html b/Walmart's Flipkart and IRFC prepare for an IPO in the US.html index e824879..82be2b5 100644 --- a/Walmart's Flipkart and IRFC prepare for an IPO in the US.html +++ b/Walmart's Flipkart and IRFC prepare for an IPO in the US.html @@ -346,13 +346,8 @@ The amalgamation of the offline and online retail under one brolly would result Walmart India paid INR 4,451 crores in paying for property in exchange, which illustrated about 85% of the company's total expenditures. The previous year, the organization had paid 88 % of its expenditures on the same. Investment of property in exchange has always been one of the important sectors of expenditure for Walmart India as these are finished interests that support the organization in administering its company.  -Walmart India’s US parent, Walmart had reported a 5.6 % increase in its revenue to $137.7 billion from $130.4 billion for July 2021 financial year. However, its international business witnessed a fall of 6.8 % partly due to the Covid Pandemic in India. Walmart International had reported net sales of $27.2 billion for the May-July quarter down for $29.1 billion to the May-July quarter of Financial Year 2020. Flipkart has aforementioned that its monthly active customers figure streamed 45% in the financial year that led to March 2020, as compared to the previous year and these happy customers are making 30% more transactions now. The 13-year-old firm said it recently surpassed a data of 1.5 billion visits per month. According to a report by consultancy firm RedSeer, Indian retail is anticipated to grow to $1.3 trillion by 2025 at a 6 % Compound Annual Growth Rate (CAGR).

- - Vote - - -
- +Walmart India’s US parent, Walmart had reported a 5.6 % increase in its revenue to $137.7 billion from $130.4 billion for July 2021 financial year. However, its international business witnessed a fall of 6.8 % partly due to the Covid Pandemic in India. Walmart International had reported net sales of $27.2 billion for the May-July quarter down for $29.1 billion to the May-July quarter of Financial Year 2020. Flipkart has aforementioned that its monthly active customers figure streamed 45% in the financial year that led to March 2020, as compared to the previous year and these happy customers are making 30% more transactions now. The 13-year-old firm said it recently surpassed a data of 1.5 billion visits per month. According to a report by consultancy firm RedSeer, Indian retail is anticipated to grow to $1.3 trillion by 2025 at a 6 % Compound Annual Growth Rate (CAGR).

+ diff --git a/content_collaboration1618935972531 (1).html b/content_collaboration1618935972531 (1).html index 700e6aa..274bc13 100644 --- a/content_collaboration1618935972531 (1).html +++ b/content_collaboration1618935972531 (1).html @@ -693,13 +693,6 @@ positive impact through a commitment to explore applications of self.

-
- - Vote - - -
diff --git a/content_collaboration1621180117697.html b/content_collaboration1621180117697.html index 7afda72..affcfba 100644 --- a/content_collaboration1621180117697.html +++ b/content_collaboration1621180117697.html @@ -441,12 +441,7 @@ In-Memory Computing -Therefore, the digital revolution is considered a disruptive innovation in the field of technology advancement. All these digital trends have attracted particular attention from society and private defense stakeholders. Right from pharmaceutical to agriculture, technology disruption is a key ingredient of digital revolutionary trends in business that has the potential to change business practices, it’s processing, and services. Products like wearable technology or fashion technology, sensors enabling technology, or advanced technology such as the internet of things, artificial intelligence, systems as well as logistics technologies, robotics, computer simulation, nanotechnologies or neuroscience, etc., illustrate the impact of digital drift in almost every industry.

- - Vote - - -
+Therefore, the digital revolution is considered a disruptive innovation in the field of technology advancement. All these digital trends have attracted particular attention from society and private defense stakeholders. Right from pharmaceutical to agriculture, technology disruption is a key ingredient of digital revolutionary trends in business that has the potential to change business practices, it’s processing, and services. Products like wearable technology or fashion technology, sensors enabling technology, or advanced technology such as the internet of things, artificial intelligence, systems as well as logistics technologies, robotics, computer simulation, nanotechnologies or neuroscience, etc., illustrate the impact of digital drift in almost every industry.